File Explorer

/var/lang/lib/node_modules/npm/node_modules/spdx-expression-parse

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

0 dirs
6 files
parse.js2.8 KB · 139 lines
'use strict' // The ABNF grammar in the spec is totally ambiguous.//// This parser follows the operator precedence defined in the// `Order of Precedence and Parentheses` section. module.exports = function (tokens) {  var index = 0   function hasMore () {    return index < tokens.length  }   function token () {    return hasMore() ? tokens[index] : null  }   function next () {    if (!hasMore()) {      throw new Error()    }    index++  }   function parseOperator (operator) {    var t = token()    if (t && t.type === 'OPERATOR' && operator === t.string) {      next()      return t.string    }  }   function parseWith () {    if (parseOperator('WITH')) {      var t = token()      if (t && t.type === 'EXCEPTION') {        next()        return t.string      }      throw new Error('Expected exception after `WITH`')    }  }   function parseLicenseRef () {    // TODO: Actually, everything is concatenated into one string    // for backward-compatibility but it could be better to return    // a nice structure.    var begin = index    var string = ''    var t = token()    if (t.type === 'DOCUMENTREF') {      next()      string += 'DocumentRef-' + t.string + ':'      if (!parseOperator(':')) {        throw new Error('Expected `:` after `DocumentRef-...`')      }    }    t = token()    if (t.type === 'LICENSEREF') {      next()      string += 'LicenseRef-' + t.string      return { license: string }    }    index = begin  }   function parseLicense () {    var t = token()    if (t && t.type === 'LICENSE') {      next()      var node = { license: t.string }      if (parseOperator('+')) {        node.plus = true      }      var exception = parseWith()      if (exception) {        node.exception = exception      }      return node    }  }   function parseParenthesizedExpression () {    var left = parseOperator('(')    if (!left) {      return    }     var expr = parseExpression()     if (!parseOperator(')')) {      throw new Error('Expected `)`')    }     return expr  }   function parseAtom () {    return (      parseParenthesizedExpression() ||      parseLicenseRef() ||      parseLicense()    )  }   function makeBinaryOpParser (operator, nextParser) {    return function parseBinaryOp () {      var left = nextParser()      if (!left) {        return      }       if (!parseOperator(operator)) {        return left      }       var right = parseBinaryOp()      if (!right) {        throw new Error('Expected expression')      }      return {        left: left,        conjunction: operator.toLowerCase(),        right: right      }    }  }   var parseAnd = makeBinaryOpParser('AND', parseAtom)  var parseExpression = makeBinaryOpParser('OR', parseAnd)   var node = parseExpression()  if (!node || hasMore()) {    throw new Error('Syntax error')  }  return node}