123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- '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
- }
|