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())