Blob Blame History Raw
var Generator = require('jison').Generator
var options = {
  type: 'slr',
  moduleType: 'commonjs',
  moduleName: 'spdxparse' }

var words = [ 'AND', 'OR', 'WITH' ]

var quote = function(argument) {
  return '\'' + argument + '\'' }

var regexEscape = function(s) {
  return s.replace(/[\^\\$*+?.()|{}\[\]\/]/g, '\\$&') }

var handleLicensesAndExceptions = function() {
  var ids = require('spdx-license-ids')
  var exceptions = require('spdx-exceptions')

  // Sort tokens longest-first (both license ids and exception strings)
  var tokens = ids.concat(exceptions)
  tokens.sort(function(a, b) { return ( b.length - a.length ) })
  return tokens.map(function(t) {
    var type = ( (ids.indexOf(t) >= 0) ? 'LICENSE' : 'EXCEPTION' )
    return [ regexEscape(t), ( 'return ' + quote(type) ) ] }) }

var grammar = {
  lex: {
    macros: { },
    rules: [
      [ '$', 'return ' + quote('EOS') ],
      [ '\\s+', '/* skip whitespace */' ],
      [ '\\+', 'return ' + quote('PLUS') ],
      [ '\\(', 'return ' + quote('OPEN') ],
      [ '\\)', 'return ' + quote('CLOSE') ],
      [ ':', 'return ' + quote('COLON') ],
      [ 'DocumentRef-([0-9A-Za-z-+.]+)',
        'return ' + quote('DOCUMENTREF') ],
      [ 'LicenseRef-([0-9A-Za-z-+.]+)',
        'return ' + quote('LICENSEREF') ] ]
      .concat(words.map(function(word) {
        return [ word, 'return ' + quote(word) ] }))
      .concat(handleLicensesAndExceptions()) },
  operators: [
    [ 'left', 'OR' ],
    [ 'left', 'AND' ],
    [ 'right', 'PLUS', 'WITH' ] ],
  tokens: [
    'CLOSE',
    'COLON',
    'EXCEPTION',
    'LICENSE',
    'LICENSEREF',
    'OPEN',
    'PLUS' ]
    .concat(words)
    .join(' '),
  start: 'start',
  bnf: {
    start: [
      [ 'expression EOS', 'return $$ = $1' ] ],
    simpleExpression: [
      [ 'LICENSE',
        '$$ = { license: yytext }' ],
      [ 'LICENSE PLUS',
        '$$ = { license: $1, plus: true }' ],
      [ 'LICENSEREF',
        '$$ = { license: yytext }' ],
      [ 'DOCUMENTREF COLON LICENSEREF',
        '$$ = { license: yytext }' ] ],
    expression: [
      [ 'simpleExpression',
        '$$ = $1' ],
      [ 'simpleExpression WITH EXCEPTION',
        [ '$$ = { exception: $3 }',
          '$$.license = $1.license',
          'if ($1.hasOwnProperty(\'plus\')) {',
          '  $$.plus = $1.plus',
          '}' ]
          .join('\n') ],
      [ 'expression AND expression',
        '$$ = { conjunction: \'and\', left: $1, right: $3 }' ],
      [ 'expression OR expression',
        '$$ = { conjunction: \'or\', left: $1, right: $3 }' ],
      [ 'OPEN expression CLOSE',
        '$$ = $2' ] ] } }

console.log(new Generator(grammar, options).generate())