132 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict'
 | 
						|
 | 
						|
var licenses = []
 | 
						|
  .concat(require('spdx-license-ids'))
 | 
						|
  .concat(require('spdx-license-ids/deprecated'))
 | 
						|
var exceptions = require('spdx-exceptions')
 | 
						|
 | 
						|
module.exports = function (source) {
 | 
						|
  var index = 0
 | 
						|
 | 
						|
  function hasMore () {
 | 
						|
    return index < source.length
 | 
						|
  }
 | 
						|
 | 
						|
  // `value` can be a regexp or a string.
 | 
						|
  // If it is recognized, the matching source string is returned and
 | 
						|
  // the index is incremented. Otherwise `undefined` is returned.
 | 
						|
  function read (value) {
 | 
						|
    if (value instanceof RegExp) {
 | 
						|
      var chars = source.slice(index)
 | 
						|
      var match = chars.match(value)
 | 
						|
      if (match) {
 | 
						|
        index += match[0].length
 | 
						|
        return match[0]
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      if (source.indexOf(value, index) === index) {
 | 
						|
        index += value.length
 | 
						|
        return value
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function skipWhitespace () {
 | 
						|
    read(/[ ]*/)
 | 
						|
  }
 | 
						|
 | 
						|
  function operator () {
 | 
						|
    var string
 | 
						|
    var possibilities = ['WITH', 'AND', 'OR', '(', ')', ':', '+']
 | 
						|
    for (var i = 0; i < possibilities.length; i++) {
 | 
						|
      string = read(possibilities[i])
 | 
						|
      if (string) {
 | 
						|
        break
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (string === '+' && index > 1 && source[index - 2] === ' ') {
 | 
						|
      throw new Error('Space before `+`')
 | 
						|
    }
 | 
						|
 | 
						|
    return string && {
 | 
						|
      type: 'OPERATOR',
 | 
						|
      string: string
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function idstring () {
 | 
						|
    return read(/[A-Za-z0-9-.]+/)
 | 
						|
  }
 | 
						|
 | 
						|
  function expectIdstring () {
 | 
						|
    var string = idstring()
 | 
						|
    if (!string) {
 | 
						|
      throw new Error('Expected idstring at offset ' + index)
 | 
						|
    }
 | 
						|
    return string
 | 
						|
  }
 | 
						|
 | 
						|
  function documentRef () {
 | 
						|
    if (read('DocumentRef-')) {
 | 
						|
      var string = expectIdstring()
 | 
						|
      return { type: 'DOCUMENTREF', string: string }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function licenseRef () {
 | 
						|
    if (read('LicenseRef-')) {
 | 
						|
      var string = expectIdstring()
 | 
						|
      return { type: 'LICENSEREF', string: string }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function identifier () {
 | 
						|
    var begin = index
 | 
						|
    var string = idstring()
 | 
						|
 | 
						|
    if (licenses.indexOf(string) !== -1) {
 | 
						|
      return {
 | 
						|
        type: 'LICENSE',
 | 
						|
        string: string
 | 
						|
      }
 | 
						|
    } else if (exceptions.indexOf(string) !== -1) {
 | 
						|
      return {
 | 
						|
        type: 'EXCEPTION',
 | 
						|
        string: string
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    index = begin
 | 
						|
  }
 | 
						|
 | 
						|
  // Tries to read the next token. Returns `undefined` if no token is
 | 
						|
  // recognized.
 | 
						|
  function parseToken () {
 | 
						|
    // Ordering matters
 | 
						|
    return (
 | 
						|
      operator() ||
 | 
						|
      documentRef() ||
 | 
						|
      licenseRef() ||
 | 
						|
      identifier()
 | 
						|
    )
 | 
						|
  }
 | 
						|
 | 
						|
  var tokens = []
 | 
						|
  while (hasMore()) {
 | 
						|
    skipWhitespace()
 | 
						|
    if (!hasMore()) {
 | 
						|
      break
 | 
						|
    }
 | 
						|
 | 
						|
    var token = parseToken()
 | 
						|
    if (!token) {
 | 
						|
      throw new Error('Unexpected `' + source[index] +
 | 
						|
                      '` at offset ' + index)
 | 
						|
    }
 | 
						|
 | 
						|
    tokens.push(token)
 | 
						|
  }
 | 
						|
  return tokens
 | 
						|
}
 |