ldap-filters
Advanced tools
Sorry, the diff of this file is not supported yet
+8
-4
| var Filter = require('./index'); | ||
| var input = '(&(givenName=jenny)(sn=jensen)(|(c=us)(st=ontario)))'; | ||
| var fs = require('fs'); | ||
| input = fs.readFileSync('filter_test.txt','utf8'); | ||
| var input = ' (& (givenName=jenny)\n(sn=jensen) \n(|(c=us)\n (st=ontario)) ) '; | ||
| //var fs = require('fs'); | ||
| //input = fs.readFileSync('filter_test.txt','utf8'); | ||
| var parsed = Filter.parse(input); | ||
| parsed = Filter.parse(parsed.toString(true)); | ||
| //parsed = Filter.parse(parsed.toString(true)); | ||
| parsed = Filter.parse(input); | ||
| console.log(parsed); | ||
| /* | ||
| console.log(JSON.stringify(parsed,null,2)); | ||
| console.log(parsed + ''); | ||
| console.log(parsed.toString(true)); | ||
| */ |
+9
-1
@@ -105,5 +105,10 @@ var soundex = require('soundex'); | ||
| var pattern = filter.replace(/\*/g,'.*'); | ||
| pattern = pattern.replace(/\\([0-9a-fA-F]{2,2})/g,function(m,$1){ | ||
| var s = String.fromCharCode(parseInt($1,16)); | ||
| if (['(',')','\\','*'].indexOf(s)>=0) s = '\\x'+$1.toUpperCase(); | ||
| return s; | ||
| }); | ||
| var regex = new RegExp('^'+pattern+'$','i'); | ||
| return match.some(function(cv){ | ||
| return Filter.escape(cv).match(regex); | ||
| return cv.match(regex); | ||
| }); | ||
@@ -219,2 +224,5 @@ }; | ||
| }, | ||
| raw: function(value) { | ||
| return new Filter(this.name,'=',value); | ||
| }, | ||
| equalTo: function(value) { | ||
@@ -221,0 +229,0 @@ return new Filter(this.name,'=',this.escape(value)); |
+1370
-615
@@ -1,722 +0,1477 @@ | ||
| /* parser generated by jison 0.4.15 */ | ||
| /* | ||
| Returns a Parser object of the following structure: | ||
| module.exports = (function() { | ||
| "use strict"; | ||
| Parser: { | ||
| yy: {} | ||
| /* | ||
| * Generated by PEG.js 0.9.0. | ||
| * | ||
| * http://pegjs.org/ | ||
| */ | ||
| function peg$subclass(child, parent) { | ||
| function ctor() { this.constructor = child; } | ||
| ctor.prototype = parent.prototype; | ||
| child.prototype = new ctor(); | ||
| } | ||
| Parser.prototype: { | ||
| yy: {}, | ||
| trace: function(), | ||
| symbols_: {associative list: name ==> number}, | ||
| terminals_: {associative list: number ==> name}, | ||
| productions_: [...], | ||
| performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), | ||
| table: [...], | ||
| defaultActions: {...}, | ||
| parseError: function(str, hash), | ||
| parse: function(input), | ||
| function peg$SyntaxError(message, expected, found, location) { | ||
| this.message = message; | ||
| this.expected = expected; | ||
| this.found = found; | ||
| this.location = location; | ||
| this.name = "SyntaxError"; | ||
| lexer: { | ||
| EOF: 1, | ||
| parseError: function(str, hash), | ||
| setInput: function(input), | ||
| input: function(), | ||
| unput: function(str), | ||
| more: function(), | ||
| less: function(n), | ||
| pastInput: function(), | ||
| upcomingInput: function(), | ||
| showPosition: function(), | ||
| test_match: function(regex_match_array, rule_index), | ||
| next: function(), | ||
| lex: function(), | ||
| begin: function(condition), | ||
| popState: function(), | ||
| _currentRules: function(), | ||
| topState: function(), | ||
| pushState: function(condition), | ||
| options: { | ||
| ranges: boolean (optional: true ==> token location info will include a .range[] member) | ||
| flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) | ||
| backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) | ||
| }, | ||
| performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), | ||
| rules: [...], | ||
| conditions: {associative list: name ==> set}, | ||
| if (typeof Error.captureStackTrace === "function") { | ||
| Error.captureStackTrace(this, peg$SyntaxError); | ||
| } | ||
| } | ||
| peg$subclass(peg$SyntaxError, Error); | ||
| token location info (@$, _$, etc.): { | ||
| first_line: n, | ||
| last_line: n, | ||
| first_column: n, | ||
| last_column: n, | ||
| range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) | ||
| } | ||
| function peg$parse(input) { | ||
| var options = arguments.length > 1 ? arguments[1] : {}, | ||
| parser = this, | ||
| peg$FAILED = {}, | ||
| the parseError function receives a 'hash' object with these members for lexer and parser errors: { | ||
| text: (matched text) | ||
| token: (the produced terminal token, if any) | ||
| line: (yylineno) | ||
| } | ||
| while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { | ||
| loc: (yylloc) | ||
| expected: (string describing the set of expected tokens) | ||
| recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) | ||
| } | ||
| */ | ||
| var parser = (function(){ | ||
| var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,3],$V1=[1,28],$V2=[1,30],$V3=[7,26]; | ||
| var parser = {trace: function trace() { }, | ||
| yy: {}, | ||
| symbols_: {"error":2,"done":3,"filter":4,"LEFT_PAREN":5,"filter_comp":6,"RIGHT_PAREN":7,"and":8,"or":9,"not":10,"operation":11,"AND":12,"filter_list":13,"OR":14,"NOT":15,"some_op":16,"present":17,"ATTR_STR":18,"filter_type":19,"value_str":20,"filter_type_ambiguous":21,"APPROX":22,"GREATER_EQ":23,"LESS_EQ":24,"EQUAL":25,"VALUE_STR":26,"$accept":0,"$end":1}, | ||
| terminals_: {2:"error",5:"LEFT_PAREN",7:"RIGHT_PAREN",12:"AND",14:"OR",15:"NOT",17:"present",18:"ATTR_STR",22:"APPROX",23:"GREATER_EQ",24:"LESS_EQ",25:"EQUAL",26:"VALUE_STR"}, | ||
| productions_: [0,[3,1],[4,3],[6,1],[6,1],[6,1],[6,1],[8,2],[9,2],[10,2],[13,1],[13,2],[11,1],[11,1],[16,3],[16,3],[19,1],[19,1],[19,1],[21,1],[20,1],[20,2]], | ||
| performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { | ||
| /* this == yyval */ | ||
| peg$startRuleFunctions = { start: peg$parsestart }, | ||
| peg$startRuleFunction = peg$parsestart, | ||
| var $0 = $$.length - 1; | ||
| switch (yystate) { | ||
| case 1: | ||
| peg$c0 = function(filter) { return filter; }, | ||
| peg$c1 = "(", | ||
| peg$c2 = { type: "literal", value: "(", description: "\"(\"" }, | ||
| peg$c3 = ")", | ||
| peg$c4 = { type: "literal", value: ")", description: "\")\"" }, | ||
| peg$c5 = "&", | ||
| peg$c6 = { type: "literal", value: "&", description: "\"&\"" }, | ||
| peg$c7 = function(filters) { return Filter.AND(filters); }, | ||
| peg$c8 = "|", | ||
| peg$c9 = { type: "literal", value: "|", description: "\"|\"" }, | ||
| peg$c10 = function(filters) { return Filter.OR(filters); }, | ||
| peg$c11 = "!", | ||
| peg$c12 = { type: "literal", value: "!", description: "\"!\"" }, | ||
| peg$c13 = function(filter) { return Filter.NOT(filter); }, | ||
| peg$c14 = function(attr, comp, value) { return new Filter(attr.attribute,comp,value); }, | ||
| peg$c15 = "=", | ||
| peg$c16 = { type: "literal", value: "=", description: "\"=\"" }, | ||
| peg$c17 = "~=", | ||
| peg$c18 = { type: "literal", value: "~=", description: "\"~=\"" }, | ||
| peg$c19 = ">=", | ||
| peg$c20 = { type: "literal", value: ">=", description: "\">=\"" }, | ||
| peg$c21 = "<=", | ||
| peg$c22 = { type: "literal", value: "<=", description: "\"<=\"" }, | ||
| peg$c23 = "=*", | ||
| peg$c24 = { type: "literal", value: "=*", description: "\"=*\"" }, | ||
| peg$c25 = function(attr) { return Filter.attribute(attr.attribute).present(); }, | ||
| peg$c26 = function(attr, value) { | ||
| return new Filter(attr.attribute,'=',value); | ||
| }, | ||
| peg$c27 = "*", | ||
| peg$c28 = { type: "literal", value: "*", description: "\"*\"" }, | ||
| peg$c29 = { type: "other", description: "attribute description" }, | ||
| peg$c30 = ";", | ||
| peg$c31 = { type: "literal", value: ";", description: "\";\"" }, | ||
| peg$c32 = function(attr, opts) { | ||
| if (opts) { | ||
| opts.shift(); | ||
| opts = opts.shift(); | ||
| opts = opts.split(';'); | ||
| } | ||
| attr.options = opts || []; | ||
| return attr; | ||
| }, | ||
| peg$c33 = { type: "other", description: "attribute Type" }, | ||
| peg$c34 = function(oid) { | ||
| return { | ||
| type: 'oid', | ||
| attribute: oid | ||
| }; | ||
| }, | ||
| peg$c35 = function(name) { | ||
| return { | ||
| type: 'attribute', | ||
| attribute: name | ||
| }; | ||
| }, | ||
| peg$c36 = { type: "other", description: "attribute type chars" }, | ||
| peg$c37 = "-", | ||
| peg$c38 = { type: "literal", value: "-", description: "\"-\"" }, | ||
| peg$c39 = { type: "other", description: "OID" }, | ||
| peg$c40 = ".", | ||
| peg$c41 = { type: "literal", value: ".", description: "\".\"" }, | ||
| peg$c42 = { type: "other", description: "attribute options" }, | ||
| peg$c43 = { type: "other", description: "attribute option" }, | ||
| peg$c44 = /^[^)]/, | ||
| peg$c45 = { type: "class", value: "[^\\x29]", description: "[^\\x29]" }, | ||
| peg$c46 = "\\", | ||
| peg$c47 = { type: "literal", value: "\\", description: "\"\\\\\"" }, | ||
| peg$c48 = function(char) { return String.fromCharCode(char); }, | ||
| peg$c49 = function(value) { return parseInt(value,16); }, | ||
| peg$c50 = /^[a-fA-F0-9]/, | ||
| peg$c51 = { type: "class", value: "[a-fA-F0-9]", description: "[a-fA-F0-9]" }, | ||
| peg$c52 = { type: "other", description: "WHITESPACE" }, | ||
| peg$c53 = { type: "other", description: "SPACE" }, | ||
| peg$c54 = /^[ ]/, | ||
| peg$c55 = { type: "class", value: "[\\x20]", description: "[\\x20]" }, | ||
| peg$c56 = { type: "other", description: "TAB" }, | ||
| peg$c57 = /^[\t]/, | ||
| peg$c58 = { type: "class", value: "[\\x09]", description: "[\\x09]" }, | ||
| peg$c59 = { type: "other", description: "DIGIT" }, | ||
| peg$c60 = /^[0-9]/, | ||
| peg$c61 = { type: "class", value: "[0-9]", description: "[0-9]" }, | ||
| peg$c62 = { type: "other", description: "ALPHA" }, | ||
| peg$c63 = /^[a-zA-Z]/, | ||
| peg$c64 = { type: "class", value: "[a-zA-Z]", description: "[a-zA-Z]" }, | ||
| peg$c65 = { type: "other", description: "NEWLINE" }, | ||
| peg$c66 = "\r\n", | ||
| peg$c67 = { type: "literal", value: "\r\n", description: "\"\\r\\n\"" }, | ||
| peg$c68 = "\n", | ||
| peg$c69 = { type: "literal", value: "\n", description: "\"\\n\"" }, | ||
| return $$[$0]; | ||
| break; | ||
| case 2: | ||
| peg$currPos = 0, | ||
| peg$savedPos = 0, | ||
| peg$posDetailsCache = [{ line: 1, column: 1, seenCR: false }], | ||
| peg$maxFailPos = 0, | ||
| peg$maxFailExpected = [], | ||
| peg$silentFails = 0, | ||
| this.$ = $$[$0-1]; | ||
| break; | ||
| case 3: case 4: case 5: case 6: | ||
| this.$ = $$[$0]; | ||
| break; | ||
| case 7: | ||
| this.$ = Filter.AND($$[$0]); | ||
| break; | ||
| case 8: | ||
| peg$result; | ||
| this.$ = Filter.OR($$[$0]); | ||
| break; | ||
| case 9: | ||
| if ("startRule" in options) { | ||
| if (!(options.startRule in peg$startRuleFunctions)) { | ||
| throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); | ||
| } | ||
| this.$ = Filter.NOT($$[$0]); | ||
| break; | ||
| case 10: | ||
| peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; | ||
| } | ||
| this.$ = [ $$[$0] ]; | ||
| break; | ||
| case 11: | ||
| function text() { | ||
| return input.substring(peg$savedPos, peg$currPos); | ||
| } | ||
| $$[$0].unshift($$[$0-1]); | ||
| this.$ = $$[$0]; | ||
| break; | ||
| case 12: case 13: case 20: | ||
| function location() { | ||
| return peg$computeLocation(peg$savedPos, peg$currPos); | ||
| } | ||
| this.$ = $$[$0]; | ||
| break; | ||
| case 14: case 15: | ||
| function expected(description) { | ||
| throw peg$buildException( | ||
| null, | ||
| [{ type: "other", description: description }], | ||
| input.substring(peg$savedPos, peg$currPos), | ||
| peg$computeLocation(peg$savedPos, peg$currPos) | ||
| ); | ||
| } | ||
| this.$ = new Filter($$[$0-2],$$[$0-1],$$[$0]); | ||
| break; | ||
| case 16: | ||
| function error(message) { | ||
| throw peg$buildException( | ||
| message, | ||
| null, | ||
| input.substring(peg$savedPos, peg$currPos), | ||
| peg$computeLocation(peg$savedPos, peg$currPos) | ||
| ); | ||
| } | ||
| this.$ = '~='; | ||
| break; | ||
| case 17: | ||
| function peg$computePosDetails(pos) { | ||
| var details = peg$posDetailsCache[pos], | ||
| p, ch; | ||
| this.$ = '>='; | ||
| break; | ||
| case 18: | ||
| if (details) { | ||
| return details; | ||
| } else { | ||
| p = pos - 1; | ||
| while (!peg$posDetailsCache[p]) { | ||
| p--; | ||
| } | ||
| this.$ = '<='; | ||
| break; | ||
| case 19: | ||
| details = peg$posDetailsCache[p]; | ||
| details = { | ||
| line: details.line, | ||
| column: details.column, | ||
| seenCR: details.seenCR | ||
| }; | ||
| this.$ = '='; | ||
| break; | ||
| case 21: | ||
| while (p < pos) { | ||
| ch = input.charAt(p); | ||
| if (ch === "\n") { | ||
| if (!details.seenCR) { details.line++; } | ||
| details.column = 1; | ||
| details.seenCR = false; | ||
| } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { | ||
| details.line++; | ||
| details.column = 1; | ||
| details.seenCR = true; | ||
| } else { | ||
| details.column++; | ||
| details.seenCR = false; | ||
| } | ||
| this.$ = $$[$0-1] + $$[$0]; | ||
| break; | ||
| } | ||
| }, | ||
| table: [{3:1,4:2,5:$V0},{1:[3]},{1:[2,1]},{6:4,8:5,9:6,10:7,11:8,12:[1,9],14:[1,10],15:[1,11],16:12,17:[1,13],18:[1,14]},{7:[1,15]},{7:[2,3]},{7:[2,4]},{7:[2,5]},{7:[2,6]},{4:17,5:$V0,13:16},{4:17,5:$V0,13:18},{4:19,5:$V0},{7:[2,12]},{7:[2,13]},{19:20,21:21,22:[1,22],23:[1,23],24:[1,24],25:[1,25]},o([1,5,7],[2,2]),{7:[2,7]},{4:17,5:$V0,7:[2,10],13:26},{7:[2,8]},{7:[2,9]},{20:27,26:$V1},{20:29,26:$V1},{26:[2,16]},{26:[2,17]},{26:[2,18]},{26:[2,19]},{7:[2,11]},{7:[2,14],26:$V2},o($V3,[2,20]),{7:[2,15],26:$V2},o($V3,[2,21])], | ||
| defaultActions: {2:[2,1],5:[2,3],6:[2,4],7:[2,5],8:[2,6],12:[2,12],13:[2,13],16:[2,7],18:[2,8],19:[2,9],22:[2,16],23:[2,17],24:[2,18],25:[2,19],26:[2,11]}, | ||
| parseError: function parseError(str, hash) { | ||
| if (hash.recoverable) { | ||
| this.trace(str); | ||
| } else { | ||
| throw new Error(str); | ||
| p++; | ||
| } | ||
| peg$posDetailsCache[pos] = details; | ||
| return details; | ||
| } | ||
| } | ||
| }, | ||
| parse: function parse(input) { | ||
| var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; | ||
| var args = lstack.slice.call(arguments, 1); | ||
| var lexer = Object.create(this.lexer); | ||
| var sharedState = { yy: {} }; | ||
| for (var k in this.yy) { | ||
| if (Object.prototype.hasOwnProperty.call(this.yy, k)) { | ||
| sharedState.yy[k] = this.yy[k]; | ||
| function peg$computeLocation(startPos, endPos) { | ||
| var startPosDetails = peg$computePosDetails(startPos), | ||
| endPosDetails = peg$computePosDetails(endPos); | ||
| return { | ||
| start: { | ||
| offset: startPos, | ||
| line: startPosDetails.line, | ||
| column: startPosDetails.column | ||
| }, | ||
| end: { | ||
| offset: endPos, | ||
| line: endPosDetails.line, | ||
| column: endPosDetails.column | ||
| } | ||
| }; | ||
| } | ||
| lexer.setInput(input, sharedState.yy); | ||
| sharedState.yy.lexer = lexer; | ||
| sharedState.yy.parser = this; | ||
| if (typeof lexer.yylloc == 'undefined') { | ||
| lexer.yylloc = {}; | ||
| function peg$fail(expected) { | ||
| if (peg$currPos < peg$maxFailPos) { return; } | ||
| if (peg$currPos > peg$maxFailPos) { | ||
| peg$maxFailPos = peg$currPos; | ||
| peg$maxFailExpected = []; | ||
| } | ||
| peg$maxFailExpected.push(expected); | ||
| } | ||
| var yyloc = lexer.yylloc; | ||
| lstack.push(yyloc); | ||
| var ranges = lexer.options && lexer.options.ranges; | ||
| if (typeof sharedState.yy.parseError === 'function') { | ||
| this.parseError = sharedState.yy.parseError; | ||
| } else { | ||
| this.parseError = Object.getPrototypeOf(this).parseError; | ||
| function peg$buildException(message, expected, found, location) { | ||
| function cleanupExpected(expected) { | ||
| var i = 1; | ||
| expected.sort(function(a, b) { | ||
| if (a.description < b.description) { | ||
| return -1; | ||
| } else if (a.description > b.description) { | ||
| return 1; | ||
| } else { | ||
| return 0; | ||
| } | ||
| }); | ||
| while (i < expected.length) { | ||
| if (expected[i - 1] === expected[i]) { | ||
| expected.splice(i, 1); | ||
| } else { | ||
| i++; | ||
| } | ||
| } | ||
| } | ||
| function buildMessage(expected, found) { | ||
| function stringEscape(s) { | ||
| function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } | ||
| return s | ||
| .replace(/\\/g, '\\\\') | ||
| .replace(/"/g, '\\"') | ||
| .replace(/\x08/g, '\\b') | ||
| .replace(/\t/g, '\\t') | ||
| .replace(/\n/g, '\\n') | ||
| .replace(/\f/g, '\\f') | ||
| .replace(/\r/g, '\\r') | ||
| .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) | ||
| .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) | ||
| .replace(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) | ||
| .replace(/[\u1000-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); | ||
| } | ||
| var expectedDescs = new Array(expected.length), | ||
| expectedDesc, foundDesc, i; | ||
| for (i = 0; i < expected.length; i++) { | ||
| expectedDescs[i] = expected[i].description; | ||
| } | ||
| expectedDesc = expected.length > 1 | ||
| ? expectedDescs.slice(0, -1).join(", ") | ||
| + " or " | ||
| + expectedDescs[expected.length - 1] | ||
| : expectedDescs[0]; | ||
| foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input"; | ||
| return "Expected " + expectedDesc + " but " + foundDesc + " found."; | ||
| } | ||
| if (expected !== null) { | ||
| cleanupExpected(expected); | ||
| } | ||
| return new peg$SyntaxError( | ||
| message !== null ? message : buildMessage(expected, found), | ||
| expected, | ||
| found, | ||
| location | ||
| ); | ||
| } | ||
| function popStack(n) { | ||
| stack.length = stack.length - 2 * n; | ||
| vstack.length = vstack.length - n; | ||
| lstack.length = lstack.length - n; | ||
| function peg$parsestart() { | ||
| var s0, s1; | ||
| s0 = peg$currPos; | ||
| s1 = peg$parsefilter(); | ||
| if (s1 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c0(s1); | ||
| } | ||
| s0 = s1; | ||
| return s0; | ||
| } | ||
| _token_stack: | ||
| function lex() { | ||
| var token; | ||
| token = lexer.lex() || EOF; | ||
| if (typeof token !== 'number') { | ||
| token = self.symbols_[token] || token; | ||
| } | ||
| return token; | ||
| } | ||
| var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; | ||
| while (true) { | ||
| state = stack[stack.length - 1]; | ||
| if (this.defaultActions[state]) { | ||
| action = this.defaultActions[state]; | ||
| function peg$parsefilter() { | ||
| var s0, s1, s2, s3, s4, s5, s6; | ||
| s0 = peg$currPos; | ||
| s1 = []; | ||
| s2 = peg$parseFILL(); | ||
| while (s2 !== peg$FAILED) { | ||
| s1.push(s2); | ||
| s2 = peg$parseFILL(); | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| if (input.charCodeAt(peg$currPos) === 40) { | ||
| s2 = peg$c1; | ||
| peg$currPos++; | ||
| } else { | ||
| if (symbol === null || typeof symbol == 'undefined') { | ||
| symbol = lex(); | ||
| } | ||
| action = table[state] && table[state][symbol]; | ||
| s2 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c2); } | ||
| } | ||
| if (typeof action === 'undefined' || !action.length || !action[0]) { | ||
| var errStr = ''; | ||
| expected = []; | ||
| for (p in table[state]) { | ||
| if (this.terminals_[p] && p > TERROR) { | ||
| expected.push('\'' + this.terminals_[p] + '\''); | ||
| } | ||
| } | ||
| if (lexer.showPosition) { | ||
| errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\''; | ||
| } else { | ||
| errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\''); | ||
| } | ||
| this.parseError(errStr, { | ||
| text: lexer.match, | ||
| token: this.terminals_[symbol] || symbol, | ||
| line: lexer.yylineno, | ||
| loc: yyloc, | ||
| expected: expected | ||
| }); | ||
| if (s2 !== peg$FAILED) { | ||
| s3 = peg$parsefiltercomp(); | ||
| if (s3 !== peg$FAILED) { | ||
| if (input.charCodeAt(peg$currPos) === 41) { | ||
| s4 = peg$c3; | ||
| peg$currPos++; | ||
| } else { | ||
| s4 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c4); } | ||
| } | ||
| if (action[0] instanceof Array && action.length > 1) { | ||
| throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); | ||
| } | ||
| switch (action[0]) { | ||
| case 1: | ||
| stack.push(symbol); | ||
| vstack.push(lexer.yytext); | ||
| lstack.push(lexer.yylloc); | ||
| stack.push(action[1]); | ||
| symbol = null; | ||
| if (!preErrorSymbol) { | ||
| yyleng = lexer.yyleng; | ||
| yytext = lexer.yytext; | ||
| yylineno = lexer.yylineno; | ||
| yyloc = lexer.yylloc; | ||
| if (recovering > 0) { | ||
| recovering--; | ||
| } | ||
| if (s4 !== peg$FAILED) { | ||
| s5 = []; | ||
| s6 = peg$parseFILL(); | ||
| while (s6 !== peg$FAILED) { | ||
| s5.push(s6); | ||
| s6 = peg$parseFILL(); | ||
| } | ||
| if (s5 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c0(s3); | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| symbol = preErrorSymbol; | ||
| preErrorSymbol = null; | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| break; | ||
| case 2: | ||
| len = this.productions_[action[1]][1]; | ||
| yyval.$ = vstack[vstack.length - len]; | ||
| yyval._$ = { | ||
| first_line: lstack[lstack.length - (len || 1)].first_line, | ||
| last_line: lstack[lstack.length - 1].last_line, | ||
| first_column: lstack[lstack.length - (len || 1)].first_column, | ||
| last_column: lstack[lstack.length - 1].last_column | ||
| }; | ||
| if (ranges) { | ||
| yyval._$.range = [ | ||
| lstack[lstack.length - (len || 1)].range[0], | ||
| lstack[lstack.length - 1].range[1] | ||
| ]; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parsefiltercomp() { | ||
| var s0; | ||
| s0 = peg$parseand(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parseor(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parsenot(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parseitem(); | ||
| } | ||
| } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseand() { | ||
| var s0, s1, s2, s3, s4, s5; | ||
| s0 = peg$currPos; | ||
| if (input.charCodeAt(peg$currPos) === 38) { | ||
| s1 = peg$c5; | ||
| peg$currPos++; | ||
| } else { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c6); } | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s2 = []; | ||
| s3 = peg$parseFILL(); | ||
| while (s3 !== peg$FAILED) { | ||
| s2.push(s3); | ||
| s3 = peg$parseFILL(); | ||
| } | ||
| if (s2 !== peg$FAILED) { | ||
| s3 = peg$parsefilterlist(); | ||
| if (s3 !== peg$FAILED) { | ||
| s4 = []; | ||
| s5 = peg$parseFILL(); | ||
| while (s5 !== peg$FAILED) { | ||
| s4.push(s5); | ||
| s5 = peg$parseFILL(); | ||
| } | ||
| r = this.performAction.apply(yyval, [ | ||
| yytext, | ||
| yyleng, | ||
| yylineno, | ||
| sharedState.yy, | ||
| action[1], | ||
| vstack, | ||
| lstack | ||
| ].concat(args)); | ||
| if (typeof r !== 'undefined') { | ||
| return r; | ||
| if (s4 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c7(s3); | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| if (len) { | ||
| stack = stack.slice(0, -1 * len * 2); | ||
| vstack = vstack.slice(0, -1 * len); | ||
| lstack = lstack.slice(0, -1 * len); | ||
| } | ||
| stack.push(this.productions_[action[1]][0]); | ||
| vstack.push(yyval.$); | ||
| lstack.push(yyval._$); | ||
| newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; | ||
| stack.push(newState); | ||
| break; | ||
| case 3: | ||
| return true; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| return s0; | ||
| } | ||
| return true; | ||
| }}; | ||
| var Filter = require('./filter'); | ||
| /* generated by jison-lex 0.3.4 */ | ||
| var lexer = (function(){ | ||
| var lexer = ({ | ||
| function peg$parseor() { | ||
| var s0, s1, s2, s3, s4, s5; | ||
| EOF:1, | ||
| parseError:function parseError(str, hash) { | ||
| if (this.yy.parser) { | ||
| this.yy.parser.parseError(str, hash); | ||
| s0 = peg$currPos; | ||
| if (input.charCodeAt(peg$currPos) === 124) { | ||
| s1 = peg$c8; | ||
| peg$currPos++; | ||
| } else { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c9); } | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s2 = []; | ||
| s3 = peg$parseFILL(); | ||
| while (s3 !== peg$FAILED) { | ||
| s2.push(s3); | ||
| s3 = peg$parseFILL(); | ||
| } | ||
| if (s2 !== peg$FAILED) { | ||
| s3 = peg$parsefilterlist(); | ||
| if (s3 !== peg$FAILED) { | ||
| s4 = []; | ||
| s5 = peg$parseFILL(); | ||
| while (s5 !== peg$FAILED) { | ||
| s4.push(s5); | ||
| s5 = peg$parseFILL(); | ||
| } | ||
| if (s4 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c10(s3); | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| throw new Error(str); | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| }, | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| // resets the lexer, sets new input | ||
| setInput:function (input, yy) { | ||
| this.yy = yy || this.yy || {}; | ||
| this._input = input; | ||
| this._more = this._backtrack = this.done = false; | ||
| this.yylineno = this.yyleng = 0; | ||
| this.yytext = this.matched = this.match = ''; | ||
| this.conditionStack = ['INITIAL']; | ||
| this.yylloc = { | ||
| first_line: 1, | ||
| first_column: 0, | ||
| last_line: 1, | ||
| last_column: 0 | ||
| }; | ||
| if (this.options.ranges) { | ||
| this.yylloc.range = [0,0]; | ||
| return s0; | ||
| } | ||
| function peg$parsenot() { | ||
| var s0, s1, s2, s3, s4, s5; | ||
| s0 = peg$currPos; | ||
| if (input.charCodeAt(peg$currPos) === 33) { | ||
| s1 = peg$c11; | ||
| peg$currPos++; | ||
| } else { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c12); } | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s2 = []; | ||
| s3 = peg$parseFILL(); | ||
| while (s3 !== peg$FAILED) { | ||
| s2.push(s3); | ||
| s3 = peg$parseFILL(); | ||
| } | ||
| this.offset = 0; | ||
| return this; | ||
| }, | ||
| // consumes and returns one char from the input | ||
| input:function () { | ||
| var ch = this._input[0]; | ||
| this.yytext += ch; | ||
| this.yyleng++; | ||
| this.offset++; | ||
| this.match += ch; | ||
| this.matched += ch; | ||
| var lines = ch.match(/(?:\r\n?|\n).*/g); | ||
| if (lines) { | ||
| this.yylineno++; | ||
| this.yylloc.last_line++; | ||
| if (s2 !== peg$FAILED) { | ||
| s3 = peg$parsefilter(); | ||
| if (s3 !== peg$FAILED) { | ||
| s4 = []; | ||
| s5 = peg$parseFILL(); | ||
| while (s5 !== peg$FAILED) { | ||
| s4.push(s5); | ||
| s5 = peg$parseFILL(); | ||
| } | ||
| if (s4 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c13(s3); | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| this.yylloc.last_column++; | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| if (this.options.ranges) { | ||
| this.yylloc.range[1]++; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parsefilterlist() { | ||
| var s0, s1; | ||
| s0 = []; | ||
| s1 = peg$parsefilter(); | ||
| if (s1 !== peg$FAILED) { | ||
| while (s1 !== peg$FAILED) { | ||
| s0.push(s1); | ||
| s1 = peg$parsefilter(); | ||
| } | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| } | ||
| this._input = this._input.slice(1); | ||
| return ch; | ||
| }, | ||
| return s0; | ||
| } | ||
| // unshifts one char (or a string) into the input | ||
| unput:function (ch) { | ||
| var len = ch.length; | ||
| var lines = ch.split(/(?:\r\n?|\n)/g); | ||
| function peg$parseitem() { | ||
| var s0; | ||
| this._input = ch + this._input; | ||
| this.yytext = this.yytext.substr(0, this.yytext.length - len); | ||
| //this.yyleng -= len; | ||
| this.offset -= len; | ||
| var oldLines = this.match.split(/(?:\r\n?|\n)/g); | ||
| this.match = this.match.substr(0, this.match.length - 1); | ||
| this.matched = this.matched.substr(0, this.matched.length - 1); | ||
| s0 = peg$parsesubstring(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parsesimple(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parsepresent(); | ||
| } | ||
| } | ||
| if (lines.length - 1) { | ||
| this.yylineno -= lines.length - 1; | ||
| return s0; | ||
| } | ||
| function peg$parsesimple() { | ||
| var s0, s1, s2, s3; | ||
| s0 = peg$currPos; | ||
| s1 = peg$parseAttributeDescription(); | ||
| if (s1 !== peg$FAILED) { | ||
| s2 = peg$parsefiltertype(); | ||
| if (s2 !== peg$FAILED) { | ||
| s3 = peg$parsevalue(); | ||
| if (s3 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c14(s1, s2, s3); | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| var r = this.yylloc.range; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| this.yylloc = { | ||
| first_line: this.yylloc.first_line, | ||
| last_line: this.yylineno + 1, | ||
| first_column: this.yylloc.first_column, | ||
| last_column: lines ? | ||
| (lines.length === oldLines.length ? this.yylloc.first_column : 0) | ||
| + oldLines[oldLines.length - lines.length].length - lines[0].length : | ||
| this.yylloc.first_column - len | ||
| }; | ||
| return s0; | ||
| } | ||
| if (this.options.ranges) { | ||
| this.yylloc.range = [r[0], r[0] + this.yyleng - len]; | ||
| function peg$parsefiltertype() { | ||
| var s0; | ||
| s0 = peg$parseequal(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parseapprox(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parsegreater(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parseless(); | ||
| } | ||
| } | ||
| this.yyleng = this.yytext.length; | ||
| return this; | ||
| }, | ||
| } | ||
| // When called from action, caches matched text and appends it on next action | ||
| more:function () { | ||
| this._more = true; | ||
| return this; | ||
| }, | ||
| return s0; | ||
| } | ||
| // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. | ||
| reject:function () { | ||
| if (this.options.backtrack_lexer) { | ||
| this._backtrack = true; | ||
| function peg$parseequal() { | ||
| var s0; | ||
| if (input.charCodeAt(peg$currPos) === 61) { | ||
| s0 = peg$c15; | ||
| peg$currPos++; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c16); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseapprox() { | ||
| var s0; | ||
| if (input.substr(peg$currPos, 2) === peg$c17) { | ||
| s0 = peg$c17; | ||
| peg$currPos += 2; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c18); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parsegreater() { | ||
| var s0; | ||
| if (input.substr(peg$currPos, 2) === peg$c19) { | ||
| s0 = peg$c19; | ||
| peg$currPos += 2; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c20); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseless() { | ||
| var s0; | ||
| if (input.substr(peg$currPos, 2) === peg$c21) { | ||
| s0 = peg$c21; | ||
| peg$currPos += 2; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c22); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parsepresent() { | ||
| var s0, s1, s2; | ||
| s0 = peg$currPos; | ||
| s1 = peg$parseAttributeDescription(); | ||
| if (s1 !== peg$FAILED) { | ||
| if (input.substr(peg$currPos, 2) === peg$c23) { | ||
| s2 = peg$c23; | ||
| peg$currPos += 2; | ||
| } else { | ||
| return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), { | ||
| text: "", | ||
| token: null, | ||
| line: this.yylineno | ||
| }); | ||
| s2 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c24); } | ||
| } | ||
| return this; | ||
| }, | ||
| if (s2 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c25(s1); | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| // retain first n characters of the match | ||
| less:function (n) { | ||
| this.unput(this.match.slice(n)); | ||
| }, | ||
| return s0; | ||
| } | ||
| // displays already matched input, i.e. for error messages | ||
| pastInput:function () { | ||
| var past = this.matched.substr(0, this.matched.length - this.match.length); | ||
| return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, ""); | ||
| }, | ||
| function peg$parsesubstring() { | ||
| var s0, s1, s2, s3, s4, s5, s6, s7; | ||
| // displays upcoming input, i.e. for error messages | ||
| upcomingInput:function () { | ||
| var next = this.match; | ||
| if (next.length < 20) { | ||
| next += this._input.substr(0, 20-next.length); | ||
| s0 = peg$currPos; | ||
| s1 = peg$parseAttributeDescription(); | ||
| if (s1 !== peg$FAILED) { | ||
| s2 = peg$parseequal(); | ||
| if (s2 !== peg$FAILED) { | ||
| s3 = peg$currPos; | ||
| s4 = peg$currPos; | ||
| s5 = peg$parsevalue(); | ||
| if (s5 === peg$FAILED) { | ||
| s5 = null; | ||
| } | ||
| if (s5 !== peg$FAILED) { | ||
| s6 = peg$parseany(); | ||
| if (s6 !== peg$FAILED) { | ||
| s7 = peg$parsevalue(); | ||
| if (s7 === peg$FAILED) { | ||
| s7 = null; | ||
| } | ||
| if (s7 !== peg$FAILED) { | ||
| s5 = [s5, s6, s7]; | ||
| s4 = s5; | ||
| } else { | ||
| peg$currPos = s4; | ||
| s4 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s4; | ||
| s4 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s4; | ||
| s4 = peg$FAILED; | ||
| } | ||
| if (s4 !== peg$FAILED) { | ||
| s3 = input.substring(s3, peg$currPos); | ||
| } else { | ||
| s3 = s4; | ||
| } | ||
| if (s3 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c26(s1, s3); | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); | ||
| }, | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| // displays the character position where the lexing error occurred, i.e. for error messages | ||
| showPosition:function () { | ||
| var pre = this.pastInput(); | ||
| var c = new Array(pre.length + 1).join("-"); | ||
| return pre + this.upcomingInput() + "\n" + c + "^"; | ||
| }, | ||
| return s0; | ||
| } | ||
| // test the lexed token: return FALSE when not a match, otherwise return token | ||
| test_match:function (match, indexed_rule) { | ||
| var token, | ||
| lines, | ||
| backup; | ||
| function peg$parseany() { | ||
| var s0, s1, s2, s3, s4, s5; | ||
| if (this.options.backtrack_lexer) { | ||
| // save context | ||
| backup = { | ||
| yylineno: this.yylineno, | ||
| yylloc: { | ||
| first_line: this.yylloc.first_line, | ||
| last_line: this.last_line, | ||
| first_column: this.yylloc.first_column, | ||
| last_column: this.yylloc.last_column | ||
| }, | ||
| yytext: this.yytext, | ||
| match: this.match, | ||
| matches: this.matches, | ||
| matched: this.matched, | ||
| yyleng: this.yyleng, | ||
| offset: this.offset, | ||
| _more: this._more, | ||
| _input: this._input, | ||
| yy: this.yy, | ||
| conditionStack: this.conditionStack.slice(0), | ||
| done: this.done | ||
| }; | ||
| if (this.options.ranges) { | ||
| backup.yylloc.range = this.yylloc.range.slice(0); | ||
| s0 = peg$currPos; | ||
| s1 = peg$currPos; | ||
| if (input.charCodeAt(peg$currPos) === 42) { | ||
| s2 = peg$c27; | ||
| peg$currPos++; | ||
| } else { | ||
| s2 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c28); } | ||
| } | ||
| if (s2 !== peg$FAILED) { | ||
| s1 = input.substring(s1, peg$currPos); | ||
| } else { | ||
| s1 = s2; | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s2 = []; | ||
| s3 = peg$currPos; | ||
| s4 = peg$parsevalue(); | ||
| if (s4 !== peg$FAILED) { | ||
| if (input.charCodeAt(peg$currPos) === 42) { | ||
| s5 = peg$c27; | ||
| peg$currPos++; | ||
| } else { | ||
| s5 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c28); } | ||
| } | ||
| if (s5 !== peg$FAILED) { | ||
| s4 = [s4, s5]; | ||
| s3 = s4; | ||
| } else { | ||
| peg$currPos = s3; | ||
| s3 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s3; | ||
| s3 = peg$FAILED; | ||
| } | ||
| while (s3 !== peg$FAILED) { | ||
| s2.push(s3); | ||
| s3 = peg$currPos; | ||
| s4 = peg$parsevalue(); | ||
| if (s4 !== peg$FAILED) { | ||
| if (input.charCodeAt(peg$currPos) === 42) { | ||
| s5 = peg$c27; | ||
| peg$currPos++; | ||
| } else { | ||
| s5 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c28); } | ||
| } | ||
| if (s5 !== peg$FAILED) { | ||
| s4 = [s4, s5]; | ||
| s3 = s4; | ||
| } else { | ||
| peg$currPos = s3; | ||
| s3 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s3; | ||
| s3 = peg$FAILED; | ||
| } | ||
| } | ||
| if (s2 !== peg$FAILED) { | ||
| s1 = [s1, s2]; | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| lines = match[0].match(/(?:\r\n?|\n).*/g); | ||
| if (lines) { | ||
| this.yylineno += lines.length; | ||
| return s0; | ||
| } | ||
| function peg$parsevalue() { | ||
| var s0, s1, s2; | ||
| s0 = peg$currPos; | ||
| s1 = []; | ||
| s2 = peg$parseAttributeValue(); | ||
| if (s2 !== peg$FAILED) { | ||
| while (s2 !== peg$FAILED) { | ||
| s1.push(s2); | ||
| s2 = peg$parseAttributeValue(); | ||
| } | ||
| this.yylloc = { | ||
| first_line: this.yylloc.last_line, | ||
| last_line: this.yylineno + 1, | ||
| first_column: this.yylloc.last_column, | ||
| last_column: lines ? | ||
| lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : | ||
| this.yylloc.last_column + match[0].length | ||
| }; | ||
| this.yytext += match[0]; | ||
| this.match += match[0]; | ||
| this.matches = match; | ||
| this.yyleng = this.yytext.length; | ||
| if (this.options.ranges) { | ||
| this.yylloc.range = [this.offset, this.offset += this.yyleng]; | ||
| } else { | ||
| s1 = peg$FAILED; | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s0 = input.substring(s0, peg$currPos); | ||
| } else { | ||
| s0 = s1; | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseAttributeDescription() { | ||
| var s0, s1, s2, s3, s4; | ||
| peg$silentFails++; | ||
| s0 = peg$currPos; | ||
| s1 = peg$parseAttributeType(); | ||
| if (s1 !== peg$FAILED) { | ||
| s2 = peg$currPos; | ||
| if (input.charCodeAt(peg$currPos) === 59) { | ||
| s3 = peg$c30; | ||
| peg$currPos++; | ||
| } else { | ||
| s3 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c31); } | ||
| } | ||
| this._more = false; | ||
| this._backtrack = false; | ||
| this._input = this._input.slice(match[0].length); | ||
| this.matched += match[0]; | ||
| token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); | ||
| if (this.done && this._input) { | ||
| this.done = false; | ||
| if (s3 !== peg$FAILED) { | ||
| s4 = peg$parseoptions(); | ||
| if (s4 !== peg$FAILED) { | ||
| s3 = [s3, s4]; | ||
| s2 = s3; | ||
| } else { | ||
| peg$currPos = s2; | ||
| s2 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s2; | ||
| s2 = peg$FAILED; | ||
| } | ||
| if (token) { | ||
| return token; | ||
| } else if (this._backtrack) { | ||
| // recover context | ||
| for (var k in backup) { | ||
| this[k] = backup[k]; | ||
| } | ||
| return false; // rule action called reject() implying the next rule should be tested instead. | ||
| if (s2 === peg$FAILED) { | ||
| s2 = null; | ||
| } | ||
| return false; | ||
| }, | ||
| if (s2 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c32(s1, s2); | ||
| s0 = s1; | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c29); } | ||
| } | ||
| // return next match in input | ||
| next:function () { | ||
| if (this.done) { | ||
| return this.EOF; | ||
| return s0; | ||
| } | ||
| function peg$parseAttributeType() { | ||
| var s0, s1, s2, s3, s4, s5; | ||
| peg$silentFails++; | ||
| s0 = peg$currPos; | ||
| s1 = peg$parseLDAP_OID(); | ||
| if (s1 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c34(s1); | ||
| } | ||
| s0 = s1; | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$currPos; | ||
| s1 = peg$currPos; | ||
| s2 = peg$currPos; | ||
| s3 = peg$parseALPHA(); | ||
| if (s3 !== peg$FAILED) { | ||
| s4 = []; | ||
| s5 = peg$parseAttrTypeChars(); | ||
| while (s5 !== peg$FAILED) { | ||
| s4.push(s5); | ||
| s5 = peg$parseAttrTypeChars(); | ||
| } | ||
| if (s4 !== peg$FAILED) { | ||
| s3 = [s3, s4]; | ||
| s2 = s3; | ||
| } else { | ||
| peg$currPos = s2; | ||
| s2 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s2; | ||
| s2 = peg$FAILED; | ||
| } | ||
| if (!this._input) { | ||
| this.done = true; | ||
| if (s2 !== peg$FAILED) { | ||
| s1 = input.substring(s1, peg$currPos); | ||
| } else { | ||
| s1 = s2; | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c35(s1); | ||
| } | ||
| s0 = s1; | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c33); } | ||
| } | ||
| var token, | ||
| match, | ||
| tempMatch, | ||
| index; | ||
| if (!this._more) { | ||
| this.yytext = ''; | ||
| this.match = ''; | ||
| return s0; | ||
| } | ||
| function peg$parseAttrTypeChars() { | ||
| var s0, s1; | ||
| peg$silentFails++; | ||
| s0 = peg$parseALPHA(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parseDIGIT(); | ||
| if (s0 === peg$FAILED) { | ||
| if (input.charCodeAt(peg$currPos) === 45) { | ||
| s0 = peg$c37; | ||
| peg$currPos++; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c38); } | ||
| } | ||
| } | ||
| var rules = this._currentRules(); | ||
| for (var i = 0; i < rules.length; i++) { | ||
| tempMatch = this._input.match(this.rules[rules[i]]); | ||
| if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { | ||
| match = tempMatch; | ||
| index = i; | ||
| if (this.options.backtrack_lexer) { | ||
| token = this.test_match(tempMatch, rules[i]); | ||
| if (token !== false) { | ||
| return token; | ||
| } else if (this._backtrack) { | ||
| match = false; | ||
| continue; // rule action called reject() implying a rule MISmatch. | ||
| } else { | ||
| // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) | ||
| return false; | ||
| } | ||
| } else if (!this.options.flex) { | ||
| break; | ||
| } | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c36); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseLDAP_OID() { | ||
| var s0, s1, s2, s3, s4, s5, s6, s7; | ||
| peg$silentFails++; | ||
| s0 = peg$currPos; | ||
| s1 = peg$currPos; | ||
| s2 = []; | ||
| s3 = peg$parseDIGIT(); | ||
| if (s3 !== peg$FAILED) { | ||
| while (s3 !== peg$FAILED) { | ||
| s2.push(s3); | ||
| s3 = peg$parseDIGIT(); | ||
| } | ||
| } else { | ||
| s2 = peg$FAILED; | ||
| } | ||
| if (s2 !== peg$FAILED) { | ||
| s3 = []; | ||
| s4 = peg$currPos; | ||
| if (input.charCodeAt(peg$currPos) === 46) { | ||
| s5 = peg$c40; | ||
| peg$currPos++; | ||
| } else { | ||
| s5 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c41); } | ||
| } | ||
| if (s5 !== peg$FAILED) { | ||
| s6 = []; | ||
| s7 = peg$parseDIGIT(); | ||
| if (s7 !== peg$FAILED) { | ||
| while (s7 !== peg$FAILED) { | ||
| s6.push(s7); | ||
| s7 = peg$parseDIGIT(); | ||
| } | ||
| } else { | ||
| s6 = peg$FAILED; | ||
| } | ||
| if (s6 !== peg$FAILED) { | ||
| s5 = [s5, s6]; | ||
| s4 = s5; | ||
| } else { | ||
| peg$currPos = s4; | ||
| s4 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s4; | ||
| s4 = peg$FAILED; | ||
| } | ||
| if (match) { | ||
| token = this.test_match(match, rules[index]); | ||
| if (token !== false) { | ||
| return token; | ||
| while (s4 !== peg$FAILED) { | ||
| s3.push(s4); | ||
| s4 = peg$currPos; | ||
| if (input.charCodeAt(peg$currPos) === 46) { | ||
| s5 = peg$c40; | ||
| peg$currPos++; | ||
| } else { | ||
| s5 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c41); } | ||
| } | ||
| if (s5 !== peg$FAILED) { | ||
| s6 = []; | ||
| s7 = peg$parseDIGIT(); | ||
| if (s7 !== peg$FAILED) { | ||
| while (s7 !== peg$FAILED) { | ||
| s6.push(s7); | ||
| s7 = peg$parseDIGIT(); | ||
| } | ||
| } else { | ||
| s6 = peg$FAILED; | ||
| } | ||
| // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) | ||
| return false; | ||
| if (s6 !== peg$FAILED) { | ||
| s5 = [s5, s6]; | ||
| s4 = s5; | ||
| } else { | ||
| peg$currPos = s4; | ||
| s4 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s4; | ||
| s4 = peg$FAILED; | ||
| } | ||
| } | ||
| if (this._input === "") { | ||
| return this.EOF; | ||
| if (s3 !== peg$FAILED) { | ||
| s2 = [s2, s3]; | ||
| s1 = s2; | ||
| } else { | ||
| return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { | ||
| text: "", | ||
| token: null, | ||
| line: this.yylineno | ||
| }); | ||
| peg$currPos = s1; | ||
| s1 = peg$FAILED; | ||
| } | ||
| }, | ||
| } else { | ||
| peg$currPos = s1; | ||
| s1 = peg$FAILED; | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s0 = input.substring(s0, peg$currPos); | ||
| } else { | ||
| s0 = s1; | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c39); } | ||
| } | ||
| // return next match that has a token | ||
| lex:function lex() { | ||
| var r = this.next(); | ||
| if (r) { | ||
| return r; | ||
| return s0; | ||
| } | ||
| function peg$parseoptions() { | ||
| var s0, s1, s2, s3, s4; | ||
| peg$silentFails++; | ||
| s0 = peg$currPos; | ||
| s1 = peg$currPos; | ||
| s2 = peg$parseoption(); | ||
| if (s2 !== peg$FAILED) { | ||
| if (input.charCodeAt(peg$currPos) === 59) { | ||
| s3 = peg$c30; | ||
| peg$currPos++; | ||
| } else { | ||
| return this.lex(); | ||
| s3 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c31); } | ||
| } | ||
| }, | ||
| if (s3 !== peg$FAILED) { | ||
| s4 = peg$parseoptions(); | ||
| if (s4 !== peg$FAILED) { | ||
| s2 = [s2, s3, s4]; | ||
| s1 = s2; | ||
| } else { | ||
| peg$currPos = s1; | ||
| s1 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s1; | ||
| s1 = peg$FAILED; | ||
| } | ||
| } else { | ||
| peg$currPos = s1; | ||
| s1 = peg$FAILED; | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s0 = input.substring(s0, peg$currPos); | ||
| } else { | ||
| s0 = s1; | ||
| } | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$currPos; | ||
| s1 = peg$parseoption(); | ||
| if (s1 !== peg$FAILED) { | ||
| s0 = input.substring(s0, peg$currPos); | ||
| } else { | ||
| s0 = s1; | ||
| } | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c42); } | ||
| } | ||
| // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) | ||
| begin:function begin(condition) { | ||
| this.conditionStack.push(condition); | ||
| }, | ||
| return s0; | ||
| } | ||
| // pop the previously active lexer condition state off the condition stack | ||
| popState:function popState() { | ||
| var n = this.conditionStack.length - 1; | ||
| if (n > 0) { | ||
| return this.conditionStack.pop(); | ||
| function peg$parseoption() { | ||
| var s0, s1; | ||
| peg$silentFails++; | ||
| s0 = []; | ||
| s1 = peg$parseAttrTypeChars(); | ||
| if (s1 !== peg$FAILED) { | ||
| while (s1 !== peg$FAILED) { | ||
| s0.push(s1); | ||
| s1 = peg$parseAttrTypeChars(); | ||
| } | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c43); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseAttributeValue() { | ||
| var s0; | ||
| s0 = peg$parseEscapedCharacter(); | ||
| if (s0 === peg$FAILED) { | ||
| if (peg$c44.test(input.charAt(peg$currPos))) { | ||
| s0 = input.charAt(peg$currPos); | ||
| peg$currPos++; | ||
| } else { | ||
| return this.conditionStack[0]; | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c45); } | ||
| } | ||
| }, | ||
| } | ||
| // produce the lexer rule set which is active for the currently active lexer condition state | ||
| _currentRules:function _currentRules() { | ||
| if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { | ||
| return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; | ||
| return s0; | ||
| } | ||
| function peg$parseEscapedCharacter() { | ||
| var s0, s1, s2; | ||
| s0 = peg$currPos; | ||
| if (input.charCodeAt(peg$currPos) === 92) { | ||
| s1 = peg$c46; | ||
| peg$currPos++; | ||
| } else { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c47); } | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s2 = peg$parseASCII_VALUE(); | ||
| if (s2 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c48(s2); | ||
| s0 = s1; | ||
| } else { | ||
| return this.conditions["INITIAL"].rules; | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| }, | ||
| } else { | ||
| peg$currPos = s0; | ||
| s0 = peg$FAILED; | ||
| } | ||
| // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available | ||
| topState:function topState(n) { | ||
| n = this.conditionStack.length - 1 - Math.abs(n || 0); | ||
| if (n >= 0) { | ||
| return this.conditionStack[n]; | ||
| return s0; | ||
| } | ||
| function peg$parseASCII_VALUE() { | ||
| var s0, s1, s2, s3, s4; | ||
| s0 = peg$currPos; | ||
| s1 = peg$currPos; | ||
| s2 = peg$currPos; | ||
| s3 = peg$parseHEX_CHAR(); | ||
| if (s3 !== peg$FAILED) { | ||
| s4 = peg$parseHEX_CHAR(); | ||
| if (s4 !== peg$FAILED) { | ||
| s3 = [s3, s4]; | ||
| s2 = s3; | ||
| } else { | ||
| return "INITIAL"; | ||
| peg$currPos = s2; | ||
| s2 = peg$FAILED; | ||
| } | ||
| }, | ||
| } else { | ||
| peg$currPos = s2; | ||
| s2 = peg$FAILED; | ||
| } | ||
| if (s2 !== peg$FAILED) { | ||
| s1 = input.substring(s1, peg$currPos); | ||
| } else { | ||
| s1 = s2; | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| peg$savedPos = s0; | ||
| s1 = peg$c49(s1); | ||
| } | ||
| s0 = s1; | ||
| // alias for begin(condition) | ||
| pushState:function pushState(condition) { | ||
| this.begin(condition); | ||
| }, | ||
| return s0; | ||
| } | ||
| // return the number of states currently on the stack | ||
| stateStackSize:function stateStackSize() { | ||
| return this.conditionStack.length; | ||
| }, | ||
| options: {}, | ||
| performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) { | ||
| function peg$parseHEX_CHAR() { | ||
| var s0; | ||
| if (peg$c50.test(input.charAt(peg$currPos))) { | ||
| s0 = input.charAt(peg$currPos); | ||
| peg$currPos++; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c51); } | ||
| } | ||
| var YYSTATE=YY_START; | ||
| switch($avoiding_name_collisions) { | ||
| case 0:/**/ | ||
| break; | ||
| case 1: | ||
| var upcoming = this.upcomingInput(); | ||
| switch (upcoming[1]) { | ||
| case '&': | ||
| case '|': | ||
| case '!': | ||
| break; | ||
| return s0; | ||
| } | ||
| default: | ||
| this.begin("ATTR"); | ||
| break; | ||
| function peg$parseFILL() { | ||
| var s0, s1; | ||
| peg$silentFails++; | ||
| s0 = peg$parseSPACE(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parseTAB(); | ||
| if (s0 === peg$FAILED) { | ||
| s0 = peg$parseSEP(); | ||
| } | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c52); } | ||
| } | ||
| return s0; | ||
| } | ||
| return "LEFT_PAREN"; | ||
| break; | ||
| case 2:return "RIGHT_PAREN"; | ||
| break; | ||
| case 3:return "AND"; | ||
| break; | ||
| case 4:return "OR"; | ||
| break; | ||
| case 5:return "NOT"; | ||
| break; | ||
| case 6:this.begin("VALUE"); return "APPROX"; | ||
| break; | ||
| case 7:this.begin("VALUE"); return "GREATER_EQ"; | ||
| break; | ||
| case 8:this.begin("VALUE"); return "LESS_EQ"; | ||
| break; | ||
| case 9:this.begin("VALUE"); return "EQUAL"; | ||
| break; | ||
| case 10:return "STAR"; | ||
| break; | ||
| case 11:return "VALUE_STR"; | ||
| break; | ||
| case 12:return "VALUE_STR"; | ||
| break; | ||
| case 13:return "VALUE_STR"; | ||
| break; | ||
| case 14:return "VALUE_STR"; | ||
| break; | ||
| case 15:return "VALUE_STR"; | ||
| break; | ||
| case 16:this.popState(); return "RIGHT_PAREN"; | ||
| break; | ||
| case 17:this.popState(); return "ATTR_STR"; | ||
| break; | ||
| } | ||
| }, | ||
| rules: [/^(?:\s+)/,/^(?:\()/,/^(?:\))/,/^(?:&)/,/^(?:\|)/,/^(?:!)/,/^(?:~=)/,/^(?:>=)/,/^(?:<=)/,/^(?:=)/,/^(?:\*)/,/^(?:[^\\()]+)/,/^(?:\\\()/,/^(?:\\\))/,/^(?:\\\\)/,/^(?:\\\*)/,/^(?:\))/,/^(?:[^=><~()]+)/], | ||
| conditions: {"VALUE":{"rules":[11,12,13,14,15,16],"inclusive":true},"ATTR":{"rules":[17],"inclusive":true},"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10],"inclusive":true}} | ||
| }); | ||
| return lexer; | ||
| })(); | ||
| parser.lexer = lexer; | ||
| function Parser () { | ||
| this.yy = {}; | ||
| } | ||
| Parser.prototype = parser;parser.Parser = Parser; | ||
| return new Parser; | ||
| })(); | ||
| function peg$parseSPACE() { | ||
| var s0, s1; | ||
| if (typeof require !== 'undefined' && typeof exports !== 'undefined') { | ||
| exports.parser = parser; | ||
| exports.Parser = parser.Parser; | ||
| exports.parse = function () { return parser.parse.apply(parser, arguments); }; | ||
| exports.main = function commonjsMain(args) { | ||
| if (!args[1]) { | ||
| console.log('Usage: '+args[0]+' FILE'); | ||
| process.exit(1); | ||
| peg$silentFails++; | ||
| if (peg$c54.test(input.charAt(peg$currPos))) { | ||
| s0 = input.charAt(peg$currPos); | ||
| peg$currPos++; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c55); } | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c53); } | ||
| } | ||
| return s0; | ||
| } | ||
| var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8"); | ||
| return exports.parser.parse(source); | ||
| }; | ||
| if (typeof module !== 'undefined' && require.main === module) { | ||
| exports.main(process.argv.slice(1)); | ||
| } | ||
| } | ||
| function peg$parseTAB() { | ||
| var s0, s1; | ||
| peg$silentFails++; | ||
| if (peg$c57.test(input.charAt(peg$currPos))) { | ||
| s0 = input.charAt(peg$currPos); | ||
| peg$currPos++; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c58); } | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c56); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseDIGIT() { | ||
| var s0, s1; | ||
| peg$silentFails++; | ||
| s0 = peg$currPos; | ||
| if (peg$c60.test(input.charAt(peg$currPos))) { | ||
| s1 = input.charAt(peg$currPos); | ||
| peg$currPos++; | ||
| } else { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c61); } | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s0 = input.substring(s0, peg$currPos); | ||
| } else { | ||
| s0 = s1; | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c59); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseALPHA() { | ||
| var s0, s1; | ||
| peg$silentFails++; | ||
| s0 = peg$currPos; | ||
| if (peg$c63.test(input.charAt(peg$currPos))) { | ||
| s1 = input.charAt(peg$currPos); | ||
| peg$currPos++; | ||
| } else { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c64); } | ||
| } | ||
| if (s1 !== peg$FAILED) { | ||
| s0 = input.substring(s0, peg$currPos); | ||
| } else { | ||
| s0 = s1; | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c62); } | ||
| } | ||
| return s0; | ||
| } | ||
| function peg$parseSEP() { | ||
| var s0, s1; | ||
| peg$silentFails++; | ||
| if (input.substr(peg$currPos, 2) === peg$c66) { | ||
| s0 = peg$c66; | ||
| peg$currPos += 2; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c67); } | ||
| } | ||
| if (s0 === peg$FAILED) { | ||
| if (input.charCodeAt(peg$currPos) === 10) { | ||
| s0 = peg$c68; | ||
| peg$currPos++; | ||
| } else { | ||
| s0 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c69); } | ||
| } | ||
| } | ||
| peg$silentFails--; | ||
| if (s0 === peg$FAILED) { | ||
| s1 = peg$FAILED; | ||
| if (peg$silentFails === 0) { peg$fail(peg$c65); } | ||
| } | ||
| return s0; | ||
| } | ||
| var fs = require('fs'); | ||
| var Filter = require('./filter'); | ||
| function base64_decode(val){ | ||
| return (new Buffer(val,'base64')).toString(); | ||
| } | ||
| var _pluck = function(list,attr){ | ||
| return list.map(function(cv){ | ||
| return cv[attr]; | ||
| }); | ||
| }; | ||
| peg$result = peg$startRuleFunction(); | ||
| if (peg$result !== peg$FAILED && peg$currPos === input.length) { | ||
| return peg$result; | ||
| } else { | ||
| if (peg$result !== peg$FAILED && peg$currPos < input.length) { | ||
| peg$fail({ type: "end", description: "end of input" }); | ||
| } | ||
| throw peg$buildException( | ||
| null, | ||
| peg$maxFailExpected, | ||
| peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, | ||
| peg$maxFailPos < input.length | ||
| ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) | ||
| : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) | ||
| ); | ||
| } | ||
| } | ||
| return { | ||
| SyntaxError: peg$SyntaxError, | ||
| parse: peg$parse | ||
| }; | ||
| })(); |
+4
-3
| { | ||
| "name": "ldap-filters", | ||
| "version": "1.2.0", | ||
| "version": "2.0.0", | ||
| "description": "Library for generating, parsing, and evaluating LDAP filters", | ||
@@ -11,7 +11,8 @@ "main": "index.js", | ||
| "chai": "*", | ||
| "mocha": "*" | ||
| "mocha": "*", | ||
| "pegjs": "^0.9.0" | ||
| }, | ||
| "scripts": { | ||
| "test": "mocha --timeout 5000 test/*js", | ||
| "build": "jison lib/parser.jison -o lib/parser.js" | ||
| "build": "node_modules/.bin/pegjs lib/parser.pegjs lib/parser.js" | ||
| }, | ||
@@ -18,0 +19,0 @@ "repository": { |
+26
-10
@@ -48,3 +48,17 @@ node-ldap-filters | ||
| * **.lte(value)** - tests if value is less than or equal `(attr<=value)` | ||
| * **.raw(value)** - add an raw (escaped) attribute value `(attr=value)` | ||
| **Added in 2.x** The `.raw` method is useful for building filters that | ||
| have complex substring matches not suitable for `.startsWith()`, | ||
| `.endsWith()`, or `.contains()` — however, you will need to escape | ||
| any values that require escaping. This can be done using | ||
| `Filter.escape()` like so: | ||
| ```javascript | ||
| var match_value = '*' + Filter.escape('James (Jimmy)') + '*'; | ||
| var filter = Filter.attribute('cn').raw(match_value); | ||
| match_value == '*James \\28Jimmy\\29*' // true | ||
| ``` | ||
| #### Aggregate methods | ||
@@ -130,3 +144,3 @@ | ||
| There are three ways to run the tests: | ||
| Tests can be run from npm or manually with mocha: | ||
@@ -143,21 +157,23 @@ ```bash | ||
| The parser is built with **jison**. To re-build the parser, | ||
| you must have jison installed globally. | ||
| The parser is built with **pegjs**. To re-build the parser, | ||
| you'll need the pegjs dev dependency installed. | ||
| ```bash | ||
| # Install jison globally (need sudo?) | ||
| npm install -g jison | ||
| # Build parser with npm | ||
| npm run build | ||
| # Build manually with jison | ||
| jison lib/parser.jison -o lib/parser.js | ||
| # Build manually with pegjs | ||
| # requires pegjs command to be availble (npm i -g pegjs) | ||
| pegjs lib/parser.pegjs lib/parser.js | ||
| ``` | ||
| ## Credits | ||
| ## History | ||
| The jison parser source was originally written by | ||
| **Version 1.x and lower** used jison parser source originally written by | ||
| [tantaman](https://github.com/tantaman/) found in the | ||
| [DATS-DAP](https://github.com/tantaman/DATS-DAP) repository. | ||
| **Version 2.x and above** are using an updated original pegjs-based parser. | ||
| This version offers better RFC-compliance and improved matching for | ||
| complicated substring matches and escaped characters, as well as addressing | ||
| some bugs found in the previous jison parser. |
+18
-0
@@ -193,3 +193,21 @@ var should = require('chai').should(); | ||
| it('matches substrings with multiple *\'s',function(done){ | ||
| var filter = Filter.attribute('cn').raw('*jen* jo*e*'); | ||
| expect(filter.match({ cn: 'Jenny Jones' })).to.be.true; | ||
| done(); | ||
| }); | ||
| it('match embedded escape characters',function(done){ | ||
| var filter = Filter.attribute('cn').raw('jenny\\2a \\28jones\\29 \\5c'); | ||
| expect(filter.match({ cn: 'Jenny* (Jones) \\' })).to.be.true; | ||
| done(); | ||
| }); | ||
| it('matches embedded escape characters with substring',function(done){ | ||
| var filter = Filter.attribute('cn').raw('*jenny\\2a j*s*'); | ||
| expect(filter.match({ cn: 'Jenny* Jones' })).to.be.true; | ||
| done(); | ||
| }); | ||
| }); | ||
+19
-0
@@ -20,2 +20,9 @@ var should = require('chai').should(); | ||
| it('parses a funny character value',function(done){ | ||
| var filter = '(orgUnit=%)'; | ||
| var parsed = Filter.parse(filter); | ||
| parsed.toString().should.be.equal(filter); | ||
| done(); | ||
| }); | ||
| it('parse more complex filter',function(done){ | ||
@@ -59,3 +66,15 @@ var filter = '(&(sn=smith)(gn=john)(!(age=5)))'; | ||
| it('fails on incorrect format past first correct filter parse',function(done){ | ||
| var filter = '(&(sn=smith))\n(uuid=3) f'; | ||
| assert.throws(function(){Filter.parse(filter);}, Error); | ||
| done(); | ||
| }); | ||
| it('allows whitespace',function(done){ | ||
| var filter = ' (& (sn=smith) \n ) '; | ||
| Filter.parse(filter).toString().should.be.equal('(&(sn=smith))'); | ||
| done(); | ||
| }); | ||
| }); | ||
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
71350
38.57%19
5.56%1955
58.43%177
9.94%3
50%4
100%1
Infinity%