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