@filtron/core
Advanced tools
+3
-3
@@ -1,5 +0,5 @@ | ||
| var V={Tab:9,Newline:10,CarriageReturn:13,Space:32,Bang:33,Quote:34,LParen:40,RParen:41,Comma:44,Minus:45,Dot:46,Slash:47,Zero:48,Nine:57,Colon:58,LessThan:60,Equals:61,GreaterThan:62,Question:63,UpperA:65,UpperZ:90,LBracket:91,Backslash:92,RBracket:93,Underscore:95,LowerA:97,LowerN:110,LowerR:114,LowerT:116,LowerZ:122,Tilde:126};class G extends Error{position;constructor(N,A){super(N);this.position=A;this.name="LexerError"}}class I{pos=0;input;length;constructor(N){this.input=N,this.length=N.length}readString(){let N=this.input,A=this.length,O=this.pos,B=this.pos+1,M=!1,b=B;while(B<A){let R=N.charCodeAt(B);if(R===V.Quote)return this.pos=B+1,{type:"STRING",value:N.slice(b,B),start:O,end:this.pos};if(R===V.Backslash){M=!0;break}B++}if(M){B=b;let R="",z=B;while(B<A){let D=N.charCodeAt(B);if(D===V.Quote)return R+=N.slice(z,B),this.pos=B+1,{type:"STRING",value:R,start:O,end:this.pos};if(D===V.Backslash){R+=N.slice(z,B),B++;let H=N.charCodeAt(B);switch(B++,H){case V.LowerN:R+=` | ||
| `;break;case V.LowerT:R+="\t";break;case V.LowerR:R+="\r";break;case V.Backslash:R+="\\";break;case V.Quote:R+='"';break;default:R+=String.fromCharCode(H)}z=B;continue}B++}}throw new G("Unterminated string literal",O)}readNumber(){let N=this.input,A=this.length,O=this.pos,B=this.pos,M=!1;if(N.charCodeAt(B)===V.Minus)M=!0,B++;let b=0;while(B<A){let R=N.charCodeAt(B);if(R<V.Zero||R>V.Nine)break;b=b*10+(R-V.Zero),B++}if(B<A&&N.charCodeAt(B)===V.Dot&&B+1<A){let R=N.charCodeAt(B+1);if(R>=V.Zero&&R<=V.Nine){B++;let z=0,D=1;while(B<A){let J=N.charCodeAt(B);if(J<V.Zero||J>V.Nine)break;z=z*10+(J-V.Zero),D*=10,B++}this.pos=B;let H=b+z/D;return{type:"NUMBER",value:M?-H:H,start:O,end:B}}}return this.pos=B,{type:"NUMBER",value:M?-b:b,start:O,end:B}}readIdentifier(){let N=this.input,A=this.length,O=this.pos,B=this.pos;while(B<A){let b=N.charCodeAt(B);if(b>=V.LowerA&&b<=V.LowerZ||b>=V.UpperA&&b<=V.UpperZ||b>=V.Zero&&b<=V.Nine||b===V.Underscore)B++;else break}this.pos=B;let M=B-O;if(M>=2&&M<=6){let b=N.charCodeAt(O)|32;if(M===2){if(b===111&&(N.charCodeAt(O+1)|32)===114)return{type:"OR",value:"or",start:O,end:B}}else if(M===3){if(b===97){if((N.charCodeAt(O+1)|32)===110&&(N.charCodeAt(O+2)|32)===100)return{type:"AND",value:"and",start:O,end:B}}else if(b===110){if((N.charCodeAt(O+1)|32)===111&&(N.charCodeAt(O+2)|32)===116)return{type:"NOT",value:"not",start:O,end:B}}}else if(M===4){if(b===116){if((N.charCodeAt(O+1)|32)===114&&(N.charCodeAt(O+2)|32)===117&&(N.charCodeAt(O+3)|32)===101)return{type:"TRUE",value:!0,start:O,end:B}}}else if(M===5){if(b===102){if((N.charCodeAt(O+1)|32)===97&&(N.charCodeAt(O+2)|32)===108&&(N.charCodeAt(O+3)|32)===115&&(N.charCodeAt(O+4)|32)===101)return{type:"FALSE",value:!1,start:O,end:B}}}else if(M===6){if(b===101){if((N.charCodeAt(O+1)|32)===120&&(N.charCodeAt(O+2)|32)===105&&(N.charCodeAt(O+3)|32)===115&&(N.charCodeAt(O+4)|32)===116&&(N.charCodeAt(O+5)|32)===115)return{type:"EXISTS",value:"exists",start:O,end:B}}}}return{type:"IDENT",value:N.slice(O,B),start:O,end:B}}next(){let N=this.input,A=this.length,O=this.pos;while(O<A){let b=N.charCodeAt(O);if(b===V.Space||b===V.Tab||b===V.Newline||b===V.CarriageReturn){O++;continue}if(b===V.Slash&&O+1<A&&N.charCodeAt(O+1)===V.Slash){O+=2;while(O<A&&N.charCodeAt(O)!==V.Newline)O++;continue}break}if(this.pos=O,O>=this.length)return{type:"EOF",value:"",start:O,end:O};let B=N.charCodeAt(O);switch(B){case V.LParen:return this.pos=O+1,{type:"LPAREN",value:"(",start:O,end:O+1};case V.RParen:return this.pos=O+1,{type:"RPAREN",value:")",start:O,end:O+1};case V.LBracket:return this.pos=O+1,{type:"LBRACKET",value:"[",start:O,end:O+1};case V.RBracket:return this.pos=O+1,{type:"RBRACKET",value:"]",start:O,end:O+1};case V.Comma:return this.pos=O+1,{type:"COMMA",value:",",start:O,end:O+1};case V.Question:return this.pos=O+1,{type:"QUESTION",value:"?",start:O,end:O+1};case V.Equals:return this.pos=O+1,{type:"EQ",value:"=",start:O,end:O+1};case V.Tilde:return this.pos=O+1,{type:"LIKE",value:"~",start:O,end:O+1};case V.Colon:return this.pos=O+1,{type:"COLON",value:":",start:O,end:O+1}}let M=O+1<this.length?N.charCodeAt(O+1):0;if(B===V.Bang){if(M===V.Equals)return this.pos=O+2,{type:"NEQ",value:"!=",start:O,end:O+2};if(M===V.Colon)return this.pos=O+2,{type:"NOT_COLON",value:"!:",start:O,end:O+2}}if(B===V.GreaterThan){if(M===V.Equals)return this.pos=O+2,{type:"GTE",value:">=",start:O,end:O+2};return this.pos=O+1,{type:"GT",value:">",start:O,end:O+1}}if(B===V.LessThan){if(M===V.Equals)return this.pos=O+2,{type:"LTE",value:"<=",start:O,end:O+2};return this.pos=O+1,{type:"LT",value:"<",start:O,end:O+1}}if(B===V.Dot){if(M===V.Dot)return this.pos=O+2,{type:"DOTDOT",value:"..",start:O,end:O+2};return this.pos=O+1,{type:"DOT",value:".",start:O,end:O+1}}if(B===V.Quote)return this.readString();if(B>=V.Zero&&B<=V.Nine)return this.readNumber();if(B===V.Minus&&M>=V.Zero&&M<=V.Nine)return this.readNumber();if(B>=V.LowerA&&B<=V.LowerZ||B>=V.UpperA&&B<=V.UpperZ||B===V.Underscore)return this.readIdentifier();throw new G(`Unexpected character: '${N[O]}'`,O)}}class j extends Error{position;constructor(N,A){super(N);this.position=A;this.name="ParseError"}}class W{lexer;current;nextToken=null;constructor(N){this.lexer=new I(N),this.current=this.lexer.next()}advance(){let N=this.current;if(this.nextToken)this.current=this.nextToken,this.nextToken=null;else this.current=this.lexer.next();return N}check(N){return this.current.type===N}expect(N,A){if(this.current.type!==N){let O=A??`Expected ${N}, got ${this.current.type}`;throw new j(O,this.current.start)}return this.advance()}parse(){if(this.check("EOF"))throw new j("Empty query",0);let N=this.parseOrExpression();if(!this.check("EOF"))throw new j(`Unexpected token: ${this.current.type}`,this.current.start);return N}parseOrExpression(){let N=this.parseAndExpression();while(this.check("OR")){this.advance();let A=this.parseAndExpression();N={type:"or",left:N,right:A}}return N}parseAndExpression(){let N=this.parseNotExpression();while(this.check("AND")){this.advance();let A=this.parseNotExpression();N={type:"and",left:N,right:A}}return N}parseNotExpression(){if(this.check("NOT"))return this.advance(),{type:"not",expression:this.parseNotExpression()};return this.parsePrimaryExpression()}parsePrimaryExpression(){if(this.check("LPAREN")){this.advance();let N=this.parseOrExpression();return this.expect("RPAREN","Expected closing parenthesis"),N}return this.parseFieldExpression()}parseFieldExpression(){let N=this.parseFieldName(),A=this.current.type;if(A==="QUESTION"||A==="EXISTS")return this.advance(),{type:"exists",field:N};if(A==="COLON"&&this.peekNextIsLBracket())return this.advance(),this.parseOneOfArray(N,"oneOf");if(A==="NOT_COLON")return this.advance(),this.parseOneOfArray(N,"notOneOf");if(A==="EQ"||A==="NEQ"||A==="GT"||A==="GTE"||A==="LT"||A==="LTE"||A==="LIKE"||A==="COLON"){let O=this.advance(),B=this.tokenToOperator(O);if(B==="="&&this.check("NUMBER")){let R=this.advance().value;if(this.check("DOTDOT")){this.advance();let D=this.expect("NUMBER","Expected number after '..'").value;return{type:"range",field:N,min:R,max:D}}return{type:"comparison",field:N,operator:B,value:{type:"number",value:R}}}let M=this.parseValue();return{type:"comparison",field:N,operator:B,value:M}}return{type:"booleanField",field:N}}peekNextIsLBracket(){if(!this.nextToken)this.nextToken=this.lexer.next();return this.nextToken.type==="LBRACKET"}tokenToOperator(N){switch(N.type){case"EQ":return"=";case"NEQ":return"!=";case"GT":return">";case"GTE":return">=";case"LT":return"<";case"LTE":return"<=";case"LIKE":return"~";case"COLON":return":";default:throw new j(`Invalid operator: ${N.type}`,N.start)}}parseFieldName(){let A=this.expect("IDENT","Expected field name").value;while(this.check("DOT")){this.advance();let O=this.expect("IDENT","Expected identifier after '.'");A+="."+O.value}return A}parseOneOfArray(N,A){this.expect("LBRACKET","Expected '[' after operator");let O=[];if(!this.check("RBRACKET")){O.push(this.parseValue());while(this.check("COMMA"))this.advance(),O.push(this.parseValue())}if(this.expect("RBRACKET","Expected ']' to close array"),O.length===0)throw new j("Array cannot be empty",this.current.start);return{type:A,field:N,values:O}}parseValue(){let N=this.current.type;if(N==="STRING")return{type:"string",value:this.advance().value};if(N==="NUMBER")return{type:"number",value:this.advance().value};if(N==="TRUE")return this.advance(),{type:"boolean",value:!0};if(N==="FALSE")return this.advance(),{type:"boolean",value:!1};if(N==="IDENT"){let O=this.advance().value;while(this.current.type==="DOT"){this.advance();let B=this.expect("IDENT","Expected identifier after '.'");O+="."+B.value}return{type:"identifier",value:O}}throw new j(`Expected value, got ${N}`,this.current.start)}}function X(N){return new W(N).parse()}class K extends Error{position;constructor(N,A){super(N);this.position=A;this.name="FiltronParseError"}}var Y=(N)=>{try{return{success:!0,ast:X(N)}}catch(A){let O,B;if(A instanceof j||A instanceof G)O=A.message,B=A.position;else if(A instanceof Error)O=A.message;else O=String(A);return{success:!1,error:O,message:O,position:B}}},Z=(N)=>{let A=Y(N);if(A.success)return A.ast;throw new K(`Failed to parse Filtron query: ${A.error}`,A.position)};export{Z as parseOrThrow,Y as parse,G as LexerError,I as Lexer,K as FiltronParseError}; | ||
| var V={Tab:9,Newline:10,CarriageReturn:13,Space:32,Bang:33,Quote:34,LParen:40,RParen:41,Comma:44,Minus:45,Dot:46,Slash:47,Zero:48,Nine:57,Colon:58,LessThan:60,Equals:61,GreaterThan:62,Question:63,UpperA:65,UpperZ:90,LBracket:91,Backslash:92,RBracket:93,Underscore:95,LowerA:97,LowerN:110,LowerR:114,LowerT:116,LowerZ:122,Tilde:126};class G extends Error{position;constructor(N,b){super(N);this.position=b;this.name="LexerError"}}class I{pos=0;input;length;constructor(N){this.input=N,this.length=N.length}readString(){let N=this.input,b=this.length,O=this.pos,B=this.pos+1,M=!1,A=B;while(B<b){let R=N.charCodeAt(B);if(R===V.Quote)return this.pos=B+1,{type:"STRING",value:N.slice(A,B),start:O,end:this.pos};if(R===V.Backslash){M=!0;break}B++}if(M){B=A;let R="",z=B;while(B<b){let D=N.charCodeAt(B);if(D===V.Quote)return R+=N.slice(z,B),this.pos=B+1,{type:"STRING",value:R,start:O,end:this.pos};if(D===V.Backslash){R+=N.slice(z,B),B++;let H=N.charCodeAt(B);switch(B++,H){case V.LowerN:R+=` | ||
| `;break;case V.LowerT:R+="\t";break;case V.LowerR:R+="\r";break;case V.Backslash:R+="\\";break;case V.Quote:R+='"';break;default:R+=String.fromCharCode(H)}z=B;continue}B++}}throw new G("Unterminated string literal",O)}readNumber(){let N=this.input,b=this.length,O=this.pos,B=this.pos,M=!1;if(N.charCodeAt(B)===V.Minus)M=!0,B++;let A=0;while(B<b){let R=N.charCodeAt(B);if(R<V.Zero||R>V.Nine)break;A=A*10+(R-V.Zero),B++}if(B<b&&N.charCodeAt(B)===V.Dot&&B+1<b){let R=N.charCodeAt(B+1);if(R>=V.Zero&&R<=V.Nine){B++;let z=0,D=1;while(B<b){let J=N.charCodeAt(B);if(J<V.Zero||J>V.Nine)break;z=z*10+(J-V.Zero),D*=10,B++}this.pos=B;let H=A+z/D;return{type:"NUMBER",value:M?-H:H,start:O,end:B}}}return this.pos=B,{type:"NUMBER",value:M?-A:A,start:O,end:B}}readIdentifier(){let N=this.input,b=this.length,O=this.pos,B=this.pos;while(B<b){let A=N.charCodeAt(B);if(A>=V.LowerA&&A<=V.LowerZ||A>=V.UpperA&&A<=V.UpperZ||A>=V.Zero&&A<=V.Nine||A===V.Underscore)B++;else break}this.pos=B;let M=B-O;if(M>=2&&M<=6){let A=N.charCodeAt(O)|32;if(M===2){if(A===111&&(N.charCodeAt(O+1)|32)===114)return{type:"OR",start:O,end:B}}else if(M===3){if(A===97){if((N.charCodeAt(O+1)|32)===110&&(N.charCodeAt(O+2)|32)===100)return{type:"AND",start:O,end:B}}else if(A===110){if((N.charCodeAt(O+1)|32)===111&&(N.charCodeAt(O+2)|32)===116)return{type:"NOT",start:O,end:B}}}else if(M===4){if(A===116){if((N.charCodeAt(O+1)|32)===114&&(N.charCodeAt(O+2)|32)===117&&(N.charCodeAt(O+3)|32)===101)return{type:"TRUE",value:!0,start:O,end:B}}}else if(M===5){if(A===102){if((N.charCodeAt(O+1)|32)===97&&(N.charCodeAt(O+2)|32)===108&&(N.charCodeAt(O+3)|32)===115&&(N.charCodeAt(O+4)|32)===101)return{type:"FALSE",value:!1,start:O,end:B}}}else if(M===6){if(A===101){if((N.charCodeAt(O+1)|32)===120&&(N.charCodeAt(O+2)|32)===105&&(N.charCodeAt(O+3)|32)===115&&(N.charCodeAt(O+4)|32)===116&&(N.charCodeAt(O+5)|32)===115)return{type:"EXISTS",start:O,end:B}}}}return{type:"IDENT",value:N.slice(O,B),start:O,end:B}}next(){let N=this.input,b=this.length,O=this.pos;while(O<b){let A=N.charCodeAt(O);if(A===V.Space||A===V.Tab||A===V.Newline||A===V.CarriageReturn){O++;continue}if(A===V.Slash&&O+1<b&&N.charCodeAt(O+1)===V.Slash){O+=2;while(O<b&&N.charCodeAt(O)!==V.Newline)O++;continue}break}if(this.pos=O,O>=this.length)return{type:"EOF",start:O,end:O};let B=N.charCodeAt(O);switch(B){case V.LParen:return this.pos=O+1,{type:"LPAREN",start:O,end:O+1};case V.RParen:return this.pos=O+1,{type:"RPAREN",start:O,end:O+1};case V.LBracket:return this.pos=O+1,{type:"LBRACKET",start:O,end:O+1};case V.RBracket:return this.pos=O+1,{type:"RBRACKET",start:O,end:O+1};case V.Comma:return this.pos=O+1,{type:"COMMA",start:O,end:O+1};case V.Question:return this.pos=O+1,{type:"QUESTION",start:O,end:O+1};case V.Equals:return this.pos=O+1,{type:"EQ",start:O,end:O+1};case V.Tilde:return this.pos=O+1,{type:"LIKE",start:O,end:O+1};case V.Colon:return this.pos=O+1,{type:"COLON",start:O,end:O+1}}let M=O+1<this.length?N.charCodeAt(O+1):0;if(B===V.Bang){if(M===V.Equals)return this.pos=O+2,{type:"NEQ",start:O,end:O+2};if(M===V.Colon)return this.pos=O+2,{type:"NOT_COLON",start:O,end:O+2}}if(B===V.GreaterThan){if(M===V.Equals)return this.pos=O+2,{type:"GTE",start:O,end:O+2};return this.pos=O+1,{type:"GT",start:O,end:O+1}}if(B===V.LessThan){if(M===V.Equals)return this.pos=O+2,{type:"LTE",start:O,end:O+2};return this.pos=O+1,{type:"LT",start:O,end:O+1}}if(B===V.Dot){if(M===V.Dot)return this.pos=O+2,{type:"DOTDOT",start:O,end:O+2};return this.pos=O+1,{type:"DOT",start:O,end:O+1}}if(B===V.Quote)return this.readString();if(B>=V.Zero&&B<=V.Nine)return this.readNumber();if(B===V.Minus&&M>=V.Zero&&M<=V.Nine)return this.readNumber();if(B>=V.LowerA&&B<=V.LowerZ||B>=V.UpperA&&B<=V.UpperZ||B===V.Underscore)return this.readIdentifier();throw new G(`Unexpected character: '${N[O]}'`,O)}}class j extends Error{position;constructor(N,b){super(N);this.position=b;this.name="ParseError"}}class W{lexer;current;nextToken=null;constructor(N){this.lexer=new I(N),this.current=this.lexer.next()}advance(){let N=this.current;if(this.nextToken)this.current=this.nextToken,this.nextToken=null;else this.current=this.lexer.next();return N}check(N){return this.current.type===N}expect(N,b){if(this.current.type!==N){let O=b??`Expected ${N}, got ${this.current.type}`;throw new j(O,this.current.start)}return this.advance()}parse(){if(this.check("EOF"))throw new j("Empty query",0);let N=this.parseOrExpression();if(!this.check("EOF"))throw new j(`Unexpected token: ${this.current.type}`,this.current.start);return N}parseOrExpression(){let N=this.parseAndExpression();while(this.check("OR")){this.advance();let b=this.parseAndExpression();N={type:"or",left:N,right:b}}return N}parseAndExpression(){let N=this.parseNotExpression();while(this.check("AND")){this.advance();let b=this.parseNotExpression();N={type:"and",left:N,right:b}}return N}parseNotExpression(){if(this.check("NOT"))return this.advance(),{type:"not",expression:this.parseNotExpression()};return this.parsePrimaryExpression()}parsePrimaryExpression(){if(this.check("LPAREN")){this.advance();let N=this.parseOrExpression();return this.expect("RPAREN","Expected closing parenthesis"),N}return this.parseFieldExpression()}parseFieldExpression(){let N=this.parseFieldName(),b=this.current.type;if(b==="QUESTION"||b==="EXISTS")return this.advance(),{type:"exists",field:N};if(b==="COLON"&&this.peekNextIsLBracket())return this.advance(),this.parseOneOfArray(N,"oneOf");if(b==="NOT_COLON")return this.advance(),this.parseOneOfArray(N,"notOneOf");if(b==="EQ"||b==="NEQ"||b==="GT"||b==="GTE"||b==="LT"||b==="LTE"||b==="LIKE"||b==="COLON"){let O=this.advance(),B=this.tokenToOperator(O);if(B==="="&&this.check("NUMBER")){let R=this.advance().value;if(this.check("DOTDOT")){this.advance();let D=this.expect("NUMBER","Expected number after '..'").value;return{type:"range",field:N,min:R,max:D}}return{type:"comparison",field:N,operator:B,value:{type:"number",value:R}}}let M=this.parseValue();return{type:"comparison",field:N,operator:B,value:M}}return{type:"booleanField",field:N}}peekNextIsLBracket(){if(!this.nextToken)this.nextToken=this.lexer.next();return this.nextToken.type==="LBRACKET"}tokenToOperator(N){switch(N.type){case"EQ":return"=";case"NEQ":return"!=";case"GT":return">";case"GTE":return">=";case"LT":return"<";case"LTE":return"<=";case"LIKE":return"~";case"COLON":return":";default:throw new j(`Invalid operator: ${N.type}`,N.start)}}parseFieldName(){let b=this.expect("IDENT","Expected field name").value;while(this.check("DOT")){this.advance();let O=this.expect("IDENT","Expected identifier after '.'");b+="."+O.value}return b}parseOneOfArray(N,b){this.expect("LBRACKET","Expected '[' after operator");let O=[];if(!this.check("RBRACKET")){O.push(this.parseValue());while(this.check("COMMA"))this.advance(),O.push(this.parseValue())}if(this.expect("RBRACKET","Expected ']' to close array"),O.length===0)throw new j("Array cannot be empty",this.current.start);return{type:b,field:N,values:O}}parseValue(){let N=this.current.type;if(N==="STRING")return{type:"string",value:this.advance().value};if(N==="NUMBER")return{type:"number",value:this.advance().value};if(N==="TRUE")return this.advance(),{type:"boolean",value:!0};if(N==="FALSE")return this.advance(),{type:"boolean",value:!1};if(N==="IDENT"){let O=this.advance().value;while(this.check("DOT")){this.advance();let B=this.expect("IDENT","Expected identifier after '.'");O+="."+B.value}return{type:"identifier",value:O}}throw new j(`Expected value, got ${N}`,this.current.start)}}function X(N){return new W(N).parse()}class K extends Error{position;constructor(N,b){super(N);this.position=b;this.name="FiltronParseError"}}var Y=(N)=>{try{return{success:!0,ast:X(N)}}catch(b){let O,B;if(b instanceof j||b instanceof G)O=b.message,B=b.position;else if(b instanceof Error)O=b.message;else O=String(b);return{success:!1,error:O,message:O,position:B}}},Z=(N)=>{let b=Y(N);if(b.success)return b.ast;throw new K(`Failed to parse Filtron query: ${b.error}`,b.position)};export{Z as parseOrThrow,Y as parse,G as LexerError,I as Lexer,K as FiltronParseError}; | ||
| //# debugId=55F7033D8A7F4FE964756E2164756E21 | ||
| //# debugId=2694F8F687E1664164756E2164756E21 | ||
| //# sourceMappingURL=index.js.map |
@@ -5,9 +5,9 @@ { | ||
| "sourcesContent": [ | ||
| "/**\n * A Lexer for the Filtron query language\n */\n\n/**\n * Token types produced by the lexer\n */\nexport type TokenType =\n\t| \"LPAREN\"\n\t| \"RPAREN\"\n\t| \"LBRACKET\"\n\t| \"RBRACKET\"\n\t| \"COMMA\"\n\t| \"QUESTION\"\n\t| \"DOT\"\n\t| \"DOTDOT\"\n\t| \"AND\"\n\t| \"OR\"\n\t| \"NOT\"\n\t| \"EXISTS\"\n\t| \"TRUE\"\n\t| \"FALSE\"\n\t| \"EQ\"\n\t| \"NEQ\"\n\t| \"GT\"\n\t| \"GTE\"\n\t| \"LT\"\n\t| \"LTE\"\n\t| \"LIKE\"\n\t| \"COLON\"\n\t| \"NOT_COLON\"\n\t| \"STRING\"\n\t| \"NUMBER\"\n\t| \"IDENT\"\n\t| \"EOF\";\n\n/** Base token properties */\ninterface TokenBase {\n\tstart: number;\n\tend: number;\n}\n\n/** Tokens with string values (punctuation, operators, keywords, identifiers) */\nexport interface StringToken extends TokenBase {\n\ttype:\n\t\t| \"LPAREN\"\n\t\t| \"RPAREN\"\n\t\t| \"LBRACKET\"\n\t\t| \"RBRACKET\"\n\t\t| \"COMMA\"\n\t\t| \"QUESTION\"\n\t\t| \"DOT\"\n\t\t| \"DOTDOT\"\n\t\t| \"AND\"\n\t\t| \"OR\"\n\t\t| \"NOT\"\n\t\t| \"EXISTS\"\n\t\t| \"EQ\"\n\t\t| \"NEQ\"\n\t\t| \"GT\"\n\t\t| \"GTE\"\n\t\t| \"LT\"\n\t\t| \"LTE\"\n\t\t| \"LIKE\"\n\t\t| \"COLON\"\n\t\t| \"NOT_COLON\"\n\t\t| \"STRING\"\n\t\t| \"IDENT\"\n\t\t| \"EOF\";\n\tvalue: string;\n}\n\n/** Tokens with number values */\nexport interface NumberToken extends TokenBase {\n\ttype: \"NUMBER\";\n\tvalue: number;\n}\n\n/** Tokens with boolean values */\nexport interface BooleanToken extends TokenBase {\n\ttype: \"TRUE\" | \"FALSE\";\n\tvalue: boolean;\n}\n\n/**\n * Discriminated union of all token types for proper type narrowing\n */\nexport type Token = StringToken | NumberToken | BooleanToken;\n\n// Character codes\nconst C = {\n\tTab: 9,\n\tNewline: 10,\n\tCarriageReturn: 13,\n\tSpace: 32,\n\tBang: 33,\n\tQuote: 34,\n\tLParen: 40,\n\tRParen: 41,\n\tComma: 44,\n\tMinus: 45,\n\tDot: 46,\n\tSlash: 47,\n\tZero: 48,\n\tNine: 57,\n\tColon: 58,\n\tLessThan: 60,\n\tEquals: 61,\n\tGreaterThan: 62,\n\tQuestion: 63,\n\tUpperA: 65,\n\tUpperZ: 90,\n\tLBracket: 91,\n\tBackslash: 92,\n\tRBracket: 93,\n\tUnderscore: 95,\n\tLowerA: 97,\n\tLowerN: 110,\n\tLowerR: 114,\n\tLowerT: 116,\n\tLowerZ: 122,\n\tTilde: 126,\n} as const;\n\n/**\n * Lexer error with position information\n */\nexport class LexerError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic position: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"LexerError\";\n\t}\n}\n\n/**\n * Lexer for tokenizing Filtron query strings\n */\nexport class Lexer {\n\tprivate pos = 0;\n\tprivate readonly input: string;\n\tprivate readonly length: number;\n\n\tconstructor(input: string) {\n\t\tthis.input = input;\n\t\tthis.length = input.length;\n\t}\n\n\t/**\n\t * Read a string literal - fast path for no escapes\n\t */\n\tprivate readString(): Token {\n\t\tconst input = this.input;\n\t\tconst length = this.length;\n\t\tconst start = this.pos;\n\t\tlet pos = this.pos + 1; // skip opening quote\n\n\t\t// Fast path: scan for closing quote or backslash\n\t\tlet hasEscape = false;\n\t\tconst scanStart = pos;\n\t\twhile (pos < length) {\n\t\t\tconst code = input.charCodeAt(pos);\n\t\t\tif (code === C.Quote) {\n\t\t\t\t// No escapes - just slice\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"STRING\",\n\t\t\t\t\tvalue: input.slice(scanStart, pos),\n\t\t\t\t\tstart,\n\t\t\t\t\tend: this.pos,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (code === C.Backslash) {\n\t\t\t\thasEscape = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpos++;\n\t\t}\n\n\t\t// Slow path: handle escapes\n\t\tif (hasEscape) {\n\t\t\tpos = scanStart;\n\t\t\tlet result = \"\";\n\t\t\tlet chunkStart = pos;\n\n\t\t\twhile (pos < length) {\n\t\t\t\tconst code = input.charCodeAt(pos);\n\n\t\t\t\tif (code === C.Quote) {\n\t\t\t\t\tresult += input.slice(chunkStart, pos);\n\t\t\t\t\tthis.pos = pos + 1;\n\t\t\t\t\treturn { type: \"STRING\", value: result, start, end: this.pos };\n\t\t\t\t}\n\n\t\t\t\tif (code === C.Backslash) {\n\t\t\t\t\tresult += input.slice(chunkStart, pos);\n\t\t\t\t\tpos++;\n\t\t\t\t\tconst escaped = input.charCodeAt(pos);\n\t\t\t\t\tpos++;\n\t\t\t\t\tswitch (escaped) {\n\t\t\t\t\t\tcase C.LowerN:\n\t\t\t\t\t\t\tresult += \"\\n\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase C.LowerT:\n\t\t\t\t\t\t\tresult += \"\\t\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase C.LowerR:\n\t\t\t\t\t\t\tresult += \"\\r\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase C.Backslash:\n\t\t\t\t\t\t\tresult += \"\\\\\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase C.Quote:\n\t\t\t\t\t\t\tresult += '\"';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tresult += String.fromCharCode(escaped);\n\t\t\t\t\t}\n\t\t\t\t\tchunkStart = pos;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tpos++;\n\t\t\t}\n\t\t}\n\n\t\tthrow new LexerError(\"Unterminated string literal\", start);\n\t}\n\n\t/**\n\t * Read a number literal\n\t */\n\tprivate readNumber(): Token {\n\t\tconst input = this.input;\n\t\tconst length = this.length;\n\t\tconst start = this.pos;\n\t\tlet pos = this.pos;\n\n\t\t// Handle negative sign\n\t\tlet negative = false;\n\t\tif (input.charCodeAt(pos) === C.Minus) {\n\t\t\tnegative = true;\n\t\t\tpos++;\n\t\t}\n\n\t\t// Read integer part directly\n\t\tlet value = 0;\n\t\twhile (pos < length) {\n\t\t\tconst code = input.charCodeAt(pos);\n\t\t\tif (code < C.Zero || code > C.Nine) break;\n\t\t\tvalue = value * 10 + (code - C.Zero);\n\t\t\tpos++;\n\t\t}\n\n\t\t// Check for decimal\n\t\tif (pos < length && input.charCodeAt(pos) === C.Dot && pos + 1 < length) {\n\t\t\tconst nextCode = input.charCodeAt(pos + 1);\n\t\t\tif (nextCode >= C.Zero && nextCode <= C.Nine) {\n\t\t\t\tpos++; // skip dot\n\t\t\t\tlet fraction = 0;\n\t\t\t\tlet divisor = 1;\n\t\t\t\twhile (pos < length) {\n\t\t\t\t\tconst code = input.charCodeAt(pos);\n\t\t\t\t\tif (code < C.Zero || code > C.Nine) break;\n\t\t\t\t\tfraction = fraction * 10 + (code - C.Zero);\n\t\t\t\t\tdivisor *= 10;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\tthis.pos = pos;\n\t\t\t\tconst floatValue = value + fraction / divisor;\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"NUMBER\",\n\t\t\t\t\tvalue: negative ? -floatValue : floatValue,\n\t\t\t\t\tstart,\n\t\t\t\t\tend: pos,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tthis.pos = pos;\n\t\treturn {\n\t\t\ttype: \"NUMBER\",\n\t\t\tvalue: negative ? -value : value,\n\t\t\tstart,\n\t\t\tend: pos,\n\t\t};\n\t}\n\n\t/**\n\t * Read identifier with fast keyword detection\n\t */\n\tprivate readIdentifier(): Token {\n\t\tconst input = this.input;\n\t\tconst length = this.length;\n\t\tconst start = this.pos;\n\t\tlet pos = this.pos;\n\n\t\t// Read all alphanumeric characters\n\t\twhile (pos < length) {\n\t\t\tconst code = input.charCodeAt(pos);\n\t\t\tif (\n\t\t\t\t(code >= C.LowerA && code <= C.LowerZ) ||\n\t\t\t\t(code >= C.UpperA && code <= C.UpperZ) ||\n\t\t\t\t(code >= C.Zero && code <= C.Nine) ||\n\t\t\t\tcode === C.Underscore\n\t\t\t) {\n\t\t\t\tpos++;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis.pos = pos;\n\t\tconst len = pos - start;\n\n\t\t// Keyword detection based on length and first char\n\t\tif (len >= 2 && len <= 6) {\n\t\t\tconst firstCode = input.charCodeAt(start) | 0x20; // lowercase\n\n\t\t\tif (len === 2) {\n\t\t\t\t// \"or\"\n\t\t\t\tif (firstCode === 111 && (input.charCodeAt(start + 1) | 0x20) === 114) {\n\t\t\t\t\treturn { type: \"OR\", value: \"or\", start, end: pos };\n\t\t\t\t}\n\t\t\t} else if (len === 3) {\n\t\t\t\t// \"and\", \"not\"\n\t\t\t\tif (firstCode === 97) {\n\t\t\t\t\t// 'a'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 110 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 100\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"AND\", value: \"and\", start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t} else if (firstCode === 110) {\n\t\t\t\t\t// 'n'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 111 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 116\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"NOT\", value: \"not\", start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (len === 4) {\n\t\t\t\t// \"true\"\n\t\t\t\tif (firstCode === 116) {\n\t\t\t\t\t// 't'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 114 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 117 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 3) | 0x20) === 101\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"TRUE\", value: true, start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (len === 5) {\n\t\t\t\t// \"false\"\n\t\t\t\tif (firstCode === 102) {\n\t\t\t\t\t// 'f'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 97 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 108 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 3) | 0x20) === 115 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 4) | 0x20) === 101\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"FALSE\", value: false, start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (len === 6) {\n\t\t\t\t// \"exists\"\n\t\t\t\tif (firstCode === 101) {\n\t\t\t\t\t// 'e'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 120 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 105 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 3) | 0x20) === 115 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 4) | 0x20) === 116 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 5) | 0x20) === 115\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"EXISTS\", value: \"exists\", start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { type: \"IDENT\", value: input.slice(start, pos), start, end: pos };\n\t}\n\n\t/**\n\t * Get the next token\n\t */\n\tnext(): Token {\n\t\tconst input = this.input;\n\t\tconst length = this.length;\n\n\t\tlet pos = this.pos;\n\t\twhile (pos < length) {\n\t\t\tconst c = input.charCodeAt(pos);\n\t\t\tif (c === C.Space || c === C.Tab || c === C.Newline || c === C.CarriageReturn) {\n\t\t\t\tpos++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (c === C.Slash && pos + 1 < length && input.charCodeAt(pos + 1) === C.Slash) {\n\t\t\t\tpos += 2;\n\t\t\t\twhile (pos < length && input.charCodeAt(pos) !== C.Newline) {\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tthis.pos = pos;\n\n\t\tif (pos >= this.length) {\n\t\t\treturn { type: \"EOF\", value: \"\", start: pos, end: pos };\n\t\t}\n\n\t\tconst code = input.charCodeAt(pos);\n\n\t\t// Single character tokens (most common first)\n\t\tswitch (code) {\n\t\t\tcase C.LParen:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"LPAREN\", value: \"(\", start: pos, end: pos + 1 };\n\t\t\tcase C.RParen:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"RPAREN\", value: \")\", start: pos, end: pos + 1 };\n\t\t\tcase C.LBracket:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"LBRACKET\", value: \"[\", start: pos, end: pos + 1 };\n\t\t\tcase C.RBracket:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"RBRACKET\", value: \"]\", start: pos, end: pos + 1 };\n\t\t\tcase C.Comma:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"COMMA\", value: \",\", start: pos, end: pos + 1 };\n\t\t\tcase C.Question:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"QUESTION\", value: \"?\", start: pos, end: pos + 1 };\n\t\t\tcase C.Equals:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"EQ\", value: \"=\", start: pos, end: pos + 1 };\n\t\t\tcase C.Tilde:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"LIKE\", value: \"~\", start: pos, end: pos + 1 };\n\t\t\tcase C.Colon:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"COLON\", value: \":\", start: pos, end: pos + 1 };\n\t\t}\n\n\t\t// Two-character operators\n\t\tconst nextCode = pos + 1 < this.length ? input.charCodeAt(pos + 1) : 0;\n\n\t\tif (code === C.Bang) {\n\t\t\tif (nextCode === C.Equals) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"NEQ\", value: \"!=\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t\tif (nextCode === C.Colon) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"NOT_COLON\", value: \"!:\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t}\n\n\t\tif (code === C.GreaterThan) {\n\t\t\tif (nextCode === C.Equals) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"GTE\", value: \">=\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t\tthis.pos = pos + 1;\n\t\t\treturn { type: \"GT\", value: \">\", start: pos, end: pos + 1 };\n\t\t}\n\n\t\tif (code === C.LessThan) {\n\t\t\tif (nextCode === C.Equals) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"LTE\", value: \"<=\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t\tthis.pos = pos + 1;\n\t\t\treturn { type: \"LT\", value: \"<\", start: pos, end: pos + 1 };\n\t\t}\n\n\t\tif (code === C.Dot) {\n\t\t\tif (nextCode === C.Dot) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"DOTDOT\", value: \"..\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t\tthis.pos = pos + 1;\n\t\t\treturn { type: \"DOT\", value: \".\", start: pos, end: pos + 1 };\n\t\t}\n\n\t\t// String literal\n\t\tif (code === C.Quote) {\n\t\t\treturn this.readString();\n\t\t}\n\n\t\t// Number\n\t\tif (code >= C.Zero && code <= C.Nine) {\n\t\t\treturn this.readNumber();\n\t\t}\n\t\tif (code === C.Minus && nextCode >= C.Zero && nextCode <= C.Nine) {\n\t\t\treturn this.readNumber();\n\t\t}\n\n\t\t// Identifier or keyword\n\t\tif (\n\t\t\t(code >= C.LowerA && code <= C.LowerZ) ||\n\t\t\t(code >= C.UpperA && code <= C.UpperZ) ||\n\t\t\tcode === C.Underscore\n\t\t) {\n\t\t\treturn this.readIdentifier();\n\t\t}\n\n\t\tthrow new LexerError(`Unexpected character: '${input[pos]}'`, pos);\n\t}\n}\n", | ||
| "/**\n * Recursive Descent Parser for Filtron\n * https://en.wikipedia.org/wiki/Recursive_descent_parser\n *\n * Grammar (in order of precedence, lowest to highest):\n *\n * Query = OrExpression\n * OrExpression = AndExpression (OR AndExpression)*\n * AndExpression = NotExpression (AND NotExpression)*\n * NotExpression = NOT NotExpression | PrimaryExpression\n * PrimaryExpression = '(' OrExpression ')' | FieldExpression\n * FieldExpression = FieldName ('?' | EXISTS | ComparisonOp Value RangeSuffix? | OneOfOp '[' Values ']')?\n * FieldName = IDENT ('.' IDENT)*\n * Value = STRING | NUMBER | BOOLEAN | DottedIdent\n * Values = Value (',' Value)*\n * RangeSuffix = '..' NUMBER\n */\n\nimport type {\n\tASTNode,\n\tValue,\n\tComparisonOperator,\n\tComparisonExpression,\n\tOneOfExpression,\n\tNotOneOfExpression,\n\tExistsExpression,\n\tBooleanFieldExpression,\n\tRangeExpression,\n} from \"./types\";\nimport { Lexer, type Token, type TokenType } from \"./lexer\";\n\n/**\n * Parser error with position information\n */\nexport class ParseError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic position: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"ParseError\";\n\t}\n}\n\n/**\n * Parser for Filtron queries\n */\nclass Parser {\n\tprivate lexer: Lexer;\n\tprivate current: Token;\n\tprivate nextToken: Token | null = null;\n\n\tconstructor(input: string) {\n\t\tthis.lexer = new Lexer(input);\n\t\tthis.current = this.lexer.next();\n\t}\n\n\t/**\n\t * Advance to the next token and return the previous one\n\t */\n\tprivate advance(): Token {\n\t\tconst prev = this.current;\n\t\tif (this.nextToken) {\n\t\t\tthis.current = this.nextToken;\n\t\t\tthis.nextToken = null;\n\t\t} else {\n\t\t\tthis.current = this.lexer.next();\n\t\t}\n\t\treturn prev;\n\t}\n\n\t/**\n\t * Check if current token matches the given type\n\t */\n\tprivate check(type: TokenType): boolean {\n\t\treturn this.current.type === type;\n\t}\n\n\t/**\n\t * Consume a token of the expected type, or throw an error\n\t */\n\tprivate expect(type: TokenType, message?: string): Token {\n\t\tif (this.current.type !== type) {\n\t\t\tconst msg = message ?? `Expected ${type}, got ${this.current.type}`;\n\t\t\tthrow new ParseError(msg, this.current.start);\n\t\t}\n\t\treturn this.advance();\n\t}\n\n\t/**\n\t * Parse a complete query\n\t */\n\tparse(): ASTNode {\n\t\tif (this.check(\"EOF\")) {\n\t\t\tthrow new ParseError(\"Empty query\", 0);\n\t\t}\n\n\t\tconst result = this.parseOrExpression();\n\n\t\tif (!this.check(\"EOF\")) {\n\t\t\tthrow new ParseError(`Unexpected token: ${this.current.type}`, this.current.start);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Parse OR expression\n\t * OrExpression = AndExpression (OR AndExpression)*\n\t */\n\tprivate parseOrExpression(): ASTNode {\n\t\tlet left = this.parseAndExpression();\n\n\t\twhile (this.check(\"OR\")) {\n\t\t\tthis.advance();\n\t\t\tconst right = this.parseAndExpression();\n\t\t\tleft = { type: \"or\", left, right };\n\t\t}\n\n\t\treturn left;\n\t}\n\n\t/**\n\t * Parse AND expression\n\t * AndExpression = NotExpression (AND NotExpression)*\n\t */\n\tprivate parseAndExpression(): ASTNode {\n\t\tlet left = this.parseNotExpression();\n\n\t\twhile (this.check(\"AND\")) {\n\t\t\tthis.advance();\n\t\t\tconst right = this.parseNotExpression();\n\t\t\tleft = { type: \"and\", left, right };\n\t\t}\n\n\t\treturn left;\n\t}\n\n\t/**\n\t * Parse NOT expression\n\t * NotExpression = NOT NotExpression | PrimaryExpression\n\t */\n\tprivate parseNotExpression(): ASTNode {\n\t\tif (this.check(\"NOT\")) {\n\t\t\tthis.advance();\n\t\t\tconst expression = this.parseNotExpression();\n\t\t\treturn { type: \"not\", expression };\n\t\t}\n\n\t\treturn this.parsePrimaryExpression();\n\t}\n\n\t/**\n\t * Parse primary expression (highest precedence)\n\t * PrimaryExpression = '(' OrExpression ')' | FieldExpression\n\t */\n\tprivate parsePrimaryExpression(): ASTNode {\n\t\t// Parenthesized expression\n\t\tif (this.check(\"LPAREN\")) {\n\t\t\tthis.advance();\n\t\t\tconst expr = this.parseOrExpression();\n\t\t\tthis.expect(\"RPAREN\", \"Expected closing parenthesis\");\n\t\t\treturn expr;\n\t\t}\n\n\t\treturn this.parseFieldExpression();\n\t}\n\n\t/**\n\t * Parse field expression\n\t * FieldExpression = FieldName ('?' | EXISTS | ComparisonOp Value RangeSuffix? | OneOfOp '[' Values ']')?\n\t */\n\tprivate parseFieldExpression(): ASTNode {\n\t\tconst field = this.parseFieldName();\n\t\tconst t = this.current.type;\n\n\t\t// Exists check with ? or EXISTS\n\t\tif (t === \"QUESTION\" || t === \"EXISTS\") {\n\t\t\tthis.advance();\n\t\t\treturn { type: \"exists\", field } as ExistsExpression;\n\t\t}\n\n\t\t// OneOf: field : [values]\n\t\tif (t === \"COLON\" && this.peekNextIsLBracket()) {\n\t\t\tthis.advance();\n\t\t\treturn this.parseOneOfArray(field, \"oneOf\");\n\t\t}\n\n\t\t// NotOneOf: field !: [values]\n\t\tif (t === \"NOT_COLON\") {\n\t\t\tthis.advance();\n\t\t\treturn this.parseOneOfArray(field, \"notOneOf\");\n\t\t}\n\n\t\t// Comparison with operator\n\t\tif (\n\t\t\tt === \"EQ\" ||\n\t\t\tt === \"NEQ\" ||\n\t\t\tt === \"GT\" ||\n\t\t\tt === \"GTE\" ||\n\t\t\tt === \"LT\" ||\n\t\t\tt === \"LTE\" ||\n\t\t\tt === \"LIKE\" ||\n\t\t\tt === \"COLON\"\n\t\t) {\n\t\t\tconst opToken = this.advance();\n\t\t\tconst operator = this.tokenToOperator(opToken);\n\n\t\t\t// Check for range expression: field = min..max\n\t\t\tif (operator === \"=\" && this.check(\"NUMBER\")) {\n\t\t\t\tconst minToken = this.advance();\n\t\t\t\tconst min = minToken.value as number;\n\n\t\t\t\tif (this.check(\"DOTDOT\")) {\n\t\t\t\t\tthis.advance();\n\t\t\t\t\tconst maxToken = this.expect(\"NUMBER\", \"Expected number after '..'\");\n\t\t\t\t\tconst max = maxToken.value as number;\n\t\t\t\t\treturn { type: \"range\", field, min, max } as RangeExpression;\n\t\t\t\t}\n\n\t\t\t\t// Not a range, just a regular comparison with a number\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"comparison\",\n\t\t\t\t\tfield,\n\t\t\t\t\toperator,\n\t\t\t\t\tvalue: { type: \"number\", value: min },\n\t\t\t\t} as ComparisonExpression;\n\t\t\t}\n\n\t\t\tconst value = this.parseValue();\n\t\t\treturn {\n\t\t\t\ttype: \"comparison\",\n\t\t\t\tfield,\n\t\t\t\toperator,\n\t\t\t\tvalue,\n\t\t\t} as ComparisonExpression;\n\t\t}\n\n\t\t// Boolean field shorthand (just the field name)\n\t\treturn { type: \"booleanField\", field } as BooleanFieldExpression;\n\t}\n\n\t/**\n\t * Check if the token after the current one is LBRACKET\n\t * (used to distinguish : as oneOf vs : as comparison operator)\n\t */\n\tprivate peekNextIsLBracket(): boolean {\n\t\tif (!this.nextToken) {\n\t\t\tthis.nextToken = this.lexer.next();\n\t\t}\n\t\treturn this.nextToken.type === \"LBRACKET\";\n\t}\n\n\t/**\n\t * Convert a token to its corresponding comparison operator\n\t */\n\tprivate tokenToOperator(token: Token): ComparisonOperator {\n\t\tswitch (token.type) {\n\t\t\tcase \"EQ\":\n\t\t\t\treturn \"=\";\n\t\t\tcase \"NEQ\":\n\t\t\t\treturn \"!=\";\n\t\t\tcase \"GT\":\n\t\t\t\treturn \">\";\n\t\t\tcase \"GTE\":\n\t\t\t\treturn \">=\";\n\t\t\tcase \"LT\":\n\t\t\t\treturn \"<\";\n\t\t\tcase \"LTE\":\n\t\t\t\treturn \"<=\";\n\t\t\tcase \"LIKE\":\n\t\t\t\treturn \"~\";\n\t\t\tcase \"COLON\":\n\t\t\t\treturn \":\";\n\t\t\tdefault:\n\t\t\t\tthrow new ParseError(`Invalid operator: ${token.type}`, token.start);\n\t\t}\n\t}\n\n\t/**\n\t * Parse a field name (possibly dotted)\n\t * FieldName = IDENT ('.' IDENT)*\n\t */\n\tprivate parseFieldName(): string {\n\t\tconst first = this.expect(\"IDENT\", \"Expected field name\");\n\t\tlet name = first.value as string;\n\n\t\twhile (this.check(\"DOT\")) {\n\t\t\tthis.advance(); // consume .\n\t\t\tconst next = this.expect(\"IDENT\", \"Expected identifier after '.'\");\n\t\t\tname += \".\" + next.value;\n\t\t}\n\n\t\treturn name;\n\t}\n\n\t/**\n\t * Parse oneOf/notOneOf array\n\t * '[' Values ']'\n\t */\n\tprivate parseOneOfArray(\n\t\tfield: string,\n\t\ttype: \"oneOf\" | \"notOneOf\",\n\t): OneOfExpression | NotOneOfExpression {\n\t\tthis.expect(\"LBRACKET\", \"Expected '[' after operator\");\n\n\t\tconst values: Value[] = [];\n\n\t\t// Handle non-empty array\n\t\tif (!this.check(\"RBRACKET\")) {\n\t\t\tvalues.push(this.parseValue());\n\n\t\t\twhile (this.check(\"COMMA\")) {\n\t\t\t\tthis.advance(); // consume ,\n\t\t\t\tvalues.push(this.parseValue());\n\t\t\t}\n\t\t}\n\n\t\tthis.expect(\"RBRACKET\", \"Expected ']' to close array\");\n\n\t\tif (values.length === 0) {\n\t\t\tthrow new ParseError(\"Array cannot be empty\", this.current.start);\n\t\t}\n\n\t\treturn { type, field, values };\n\t}\n\n\t/**\n\t * Parse a value\n\t * Value = STRING | NUMBER | BOOLEAN | DottedIdent\n\t */\n\tprivate parseValue(): Value {\n\t\tconst t = this.current.type;\n\n\t\t// String literal\n\t\tif (t === \"STRING\") {\n\t\t\tconst token = this.advance();\n\t\t\treturn { type: \"string\", value: token.value as string };\n\t\t}\n\n\t\t// Number literal\n\t\tif (t === \"NUMBER\") {\n\t\t\tconst token = this.advance();\n\t\t\treturn { type: \"number\", value: token.value as number };\n\t\t}\n\n\t\t// Boolean literal\n\t\tif (t === \"TRUE\") {\n\t\t\tthis.advance();\n\t\t\treturn { type: \"boolean\", value: true };\n\t\t}\n\t\tif (t === \"FALSE\") {\n\t\t\tthis.advance();\n\t\t\treturn { type: \"boolean\", value: false };\n\t\t}\n\n\t\t// Identifier (possibly dotted)\n\t\tif (t === \"IDENT\") {\n\t\t\tconst first = this.advance();\n\t\t\tlet value = first.value as string;\n\n\t\t\twhile (this.current.type === \"DOT\") {\n\t\t\t\tthis.advance(); // consume .\n\t\t\t\tconst next = this.expect(\"IDENT\", \"Expected identifier after '.'\");\n\t\t\t\tvalue += \".\" + next.value;\n\t\t\t}\n\n\t\t\treturn { type: \"identifier\", value };\n\t\t}\n\n\t\tthrow new ParseError(`Expected value, got ${t}`, this.current.start);\n\t}\n}\n\n/**\n * Parse a Filtron query string into an AST\n *\n * @param input - The query string to parse\n * @returns The parsed AST\n * @throws ParseError if the query is invalid\n */\nexport function parseQuery(input: string): ASTNode {\n\tconst parser = new Parser(input);\n\treturn parser.parse();\n}\n", | ||
| "/**\n * A Lexer for the Filtron query language\n */\n\n/**\n * Token types produced by the lexer\n */\nexport type TokenType =\n\t| \"LPAREN\"\n\t| \"RPAREN\"\n\t| \"LBRACKET\"\n\t| \"RBRACKET\"\n\t| \"COMMA\"\n\t| \"QUESTION\"\n\t| \"DOT\"\n\t| \"DOTDOT\"\n\t| \"AND\"\n\t| \"OR\"\n\t| \"NOT\"\n\t| \"EXISTS\"\n\t| \"TRUE\"\n\t| \"FALSE\"\n\t| \"EQ\"\n\t| \"NEQ\"\n\t| \"GT\"\n\t| \"GTE\"\n\t| \"LT\"\n\t| \"LTE\"\n\t| \"LIKE\"\n\t| \"COLON\"\n\t| \"NOT_COLON\"\n\t| \"STRING\"\n\t| \"NUMBER\"\n\t| \"IDENT\"\n\t| \"EOF\";\n\n/** Base token properties */\ninterface TokenBase {\n\tstart: number;\n\tend: number;\n}\n\n/** Tokens with string values (string literals and identifiers) */\nexport interface StringToken extends TokenBase {\n\ttype: \"STRING\" | \"IDENT\";\n\tvalue: string;\n}\n\n/** Tokens without values (operators, punctuation, keywords, EOF) */\nexport interface SymbolToken extends TokenBase {\n\ttype:\n\t\t| \"LPAREN\"\n\t\t| \"RPAREN\"\n\t\t| \"LBRACKET\"\n\t\t| \"RBRACKET\"\n\t\t| \"COMMA\"\n\t\t| \"QUESTION\"\n\t\t| \"DOT\"\n\t\t| \"DOTDOT\"\n\t\t| \"AND\"\n\t\t| \"OR\"\n\t\t| \"NOT\"\n\t\t| \"EXISTS\"\n\t\t| \"EQ\"\n\t\t| \"NEQ\"\n\t\t| \"GT\"\n\t\t| \"GTE\"\n\t\t| \"LT\"\n\t\t| \"LTE\"\n\t\t| \"LIKE\"\n\t\t| \"COLON\"\n\t\t| \"NOT_COLON\"\n\t\t| \"EOF\";\n}\n\n/** Tokens with number values */\nexport interface NumberToken extends TokenBase {\n\ttype: \"NUMBER\";\n\tvalue: number;\n}\n\n/** Tokens with boolean values */\nexport interface BooleanToken extends TokenBase {\n\ttype: \"TRUE\" | \"FALSE\";\n\tvalue: boolean;\n}\n\n/**\n * Discriminated union of all token types for proper type narrowing\n */\nexport type Token = StringToken | NumberToken | BooleanToken | SymbolToken;\n\n// Character codes\nconst C = {\n\tTab: 9,\n\tNewline: 10,\n\tCarriageReturn: 13,\n\tSpace: 32,\n\tBang: 33,\n\tQuote: 34,\n\tLParen: 40,\n\tRParen: 41,\n\tComma: 44,\n\tMinus: 45,\n\tDot: 46,\n\tSlash: 47,\n\tZero: 48,\n\tNine: 57,\n\tColon: 58,\n\tLessThan: 60,\n\tEquals: 61,\n\tGreaterThan: 62,\n\tQuestion: 63,\n\tUpperA: 65,\n\tUpperZ: 90,\n\tLBracket: 91,\n\tBackslash: 92,\n\tRBracket: 93,\n\tUnderscore: 95,\n\tLowerA: 97,\n\tLowerN: 110,\n\tLowerR: 114,\n\tLowerT: 116,\n\tLowerZ: 122,\n\tTilde: 126,\n} as const;\n\n/**\n * Lexer error with position information\n */\nexport class LexerError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic position: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"LexerError\";\n\t}\n}\n\n/**\n * Lexer for tokenizing Filtron query strings\n */\nexport class Lexer {\n\tprivate pos = 0;\n\tprivate readonly input: string;\n\tprivate readonly length: number;\n\n\tconstructor(input: string) {\n\t\tthis.input = input;\n\t\tthis.length = input.length;\n\t}\n\n\t/**\n\t * Read a string literal - fast path for no escapes\n\t */\n\tprivate readString(): Token {\n\t\tconst input = this.input;\n\t\tconst length = this.length;\n\t\tconst start = this.pos;\n\t\tlet pos = this.pos + 1; // skip opening quote\n\n\t\t// Fast path: scan for closing quote or backslash\n\t\tlet hasEscape = false;\n\t\tconst scanStart = pos;\n\t\twhile (pos < length) {\n\t\t\tconst code = input.charCodeAt(pos);\n\t\t\tif (code === C.Quote) {\n\t\t\t\t// No escapes - just slice\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"STRING\",\n\t\t\t\t\tvalue: input.slice(scanStart, pos),\n\t\t\t\t\tstart,\n\t\t\t\t\tend: this.pos,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (code === C.Backslash) {\n\t\t\t\thasEscape = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpos++;\n\t\t}\n\n\t\t// Slow path: handle escapes\n\t\tif (hasEscape) {\n\t\t\tpos = scanStart;\n\t\t\tlet result = \"\";\n\t\t\tlet chunkStart = pos;\n\n\t\t\twhile (pos < length) {\n\t\t\t\tconst code = input.charCodeAt(pos);\n\n\t\t\t\tif (code === C.Quote) {\n\t\t\t\t\tresult += input.slice(chunkStart, pos);\n\t\t\t\t\tthis.pos = pos + 1;\n\t\t\t\t\treturn { type: \"STRING\", value: result, start, end: this.pos };\n\t\t\t\t}\n\n\t\t\t\tif (code === C.Backslash) {\n\t\t\t\t\tresult += input.slice(chunkStart, pos);\n\t\t\t\t\tpos++;\n\t\t\t\t\tconst escaped = input.charCodeAt(pos);\n\t\t\t\t\tpos++;\n\t\t\t\t\tswitch (escaped) {\n\t\t\t\t\t\tcase C.LowerN:\n\t\t\t\t\t\t\tresult += \"\\n\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase C.LowerT:\n\t\t\t\t\t\t\tresult += \"\\t\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase C.LowerR:\n\t\t\t\t\t\t\tresult += \"\\r\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase C.Backslash:\n\t\t\t\t\t\t\tresult += \"\\\\\";\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase C.Quote:\n\t\t\t\t\t\t\tresult += '\"';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tresult += String.fromCharCode(escaped);\n\t\t\t\t\t}\n\t\t\t\t\tchunkStart = pos;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tpos++;\n\t\t\t}\n\t\t}\n\n\t\tthrow new LexerError(\"Unterminated string literal\", start);\n\t}\n\n\t/**\n\t * Read a number literal\n\t */\n\tprivate readNumber(): Token {\n\t\tconst input = this.input;\n\t\tconst length = this.length;\n\t\tconst start = this.pos;\n\t\tlet pos = this.pos;\n\n\t\t// Handle negative sign\n\t\tlet negative = false;\n\t\tif (input.charCodeAt(pos) === C.Minus) {\n\t\t\tnegative = true;\n\t\t\tpos++;\n\t\t}\n\n\t\t// Read integer part directly\n\t\tlet value = 0;\n\t\twhile (pos < length) {\n\t\t\tconst code = input.charCodeAt(pos);\n\t\t\tif (code < C.Zero || code > C.Nine) break;\n\t\t\tvalue = value * 10 + (code - C.Zero);\n\t\t\tpos++;\n\t\t}\n\n\t\t// Check for decimal\n\t\tif (pos < length && input.charCodeAt(pos) === C.Dot && pos + 1 < length) {\n\t\t\tconst nextCode = input.charCodeAt(pos + 1);\n\t\t\tif (nextCode >= C.Zero && nextCode <= C.Nine) {\n\t\t\t\tpos++; // skip dot\n\t\t\t\tlet fraction = 0;\n\t\t\t\tlet divisor = 1;\n\t\t\t\twhile (pos < length) {\n\t\t\t\t\tconst code = input.charCodeAt(pos);\n\t\t\t\t\tif (code < C.Zero || code > C.Nine) break;\n\t\t\t\t\tfraction = fraction * 10 + (code - C.Zero);\n\t\t\t\t\tdivisor *= 10;\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\tthis.pos = pos;\n\t\t\t\tconst floatValue = value + fraction / divisor;\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"NUMBER\",\n\t\t\t\t\tvalue: negative ? -floatValue : floatValue,\n\t\t\t\t\tstart,\n\t\t\t\t\tend: pos,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tthis.pos = pos;\n\t\treturn {\n\t\t\ttype: \"NUMBER\",\n\t\t\tvalue: negative ? -value : value,\n\t\t\tstart,\n\t\t\tend: pos,\n\t\t};\n\t}\n\n\t/**\n\t * Read identifier with fast keyword detection\n\t */\n\tprivate readIdentifier(): Token {\n\t\tconst input = this.input;\n\t\tconst length = this.length;\n\t\tconst start = this.pos;\n\t\tlet pos = this.pos;\n\n\t\t// Read all alphanumeric characters\n\t\twhile (pos < length) {\n\t\t\tconst code = input.charCodeAt(pos);\n\t\t\tif (\n\t\t\t\t(code >= C.LowerA && code <= C.LowerZ) ||\n\t\t\t\t(code >= C.UpperA && code <= C.UpperZ) ||\n\t\t\t\t(code >= C.Zero && code <= C.Nine) ||\n\t\t\t\tcode === C.Underscore\n\t\t\t) {\n\t\t\t\tpos++;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis.pos = pos;\n\t\tconst len = pos - start;\n\n\t\t// Keyword detection based on length and first char\n\t\tif (len >= 2 && len <= 6) {\n\t\t\tconst firstCode = input.charCodeAt(start) | 0x20; // lowercase\n\n\t\t\tif (len === 2) {\n\t\t\t\t// \"or\"\n\t\t\t\tif (firstCode === 111 && (input.charCodeAt(start + 1) | 0x20) === 114) {\n\t\t\t\t\treturn { type: \"OR\", start, end: pos };\n\t\t\t\t}\n\t\t\t} else if (len === 3) {\n\t\t\t\t// \"and\", \"not\"\n\t\t\t\tif (firstCode === 97) {\n\t\t\t\t\t// 'a'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 110 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 100\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"AND\", start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t} else if (firstCode === 110) {\n\t\t\t\t\t// 'n'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 111 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 116\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"NOT\", start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (len === 4) {\n\t\t\t\t// \"true\"\n\t\t\t\tif (firstCode === 116) {\n\t\t\t\t\t// 't'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 114 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 117 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 3) | 0x20) === 101\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"TRUE\", value: true, start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (len === 5) {\n\t\t\t\t// \"false\"\n\t\t\t\tif (firstCode === 102) {\n\t\t\t\t\t// 'f'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 97 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 108 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 3) | 0x20) === 115 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 4) | 0x20) === 101\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"FALSE\", value: false, start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (len === 6) {\n\t\t\t\t// \"exists\"\n\t\t\t\tif (firstCode === 101) {\n\t\t\t\t\t// 'e'\n\t\t\t\t\tif (\n\t\t\t\t\t\t(input.charCodeAt(start + 1) | 0x20) === 120 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 2) | 0x20) === 105 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 3) | 0x20) === 115 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 4) | 0x20) === 116 &&\n\t\t\t\t\t\t(input.charCodeAt(start + 5) | 0x20) === 115\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn { type: \"EXISTS\", start, end: pos };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { type: \"IDENT\", value: input.slice(start, pos), start, end: pos };\n\t}\n\n\t/**\n\t * Get the next token\n\t */\n\tnext(): Token {\n\t\tconst input = this.input;\n\t\tconst length = this.length;\n\n\t\tlet pos = this.pos;\n\t\twhile (pos < length) {\n\t\t\tconst c = input.charCodeAt(pos);\n\t\t\tif (c === C.Space || c === C.Tab || c === C.Newline || c === C.CarriageReturn) {\n\t\t\t\tpos++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (c === C.Slash && pos + 1 < length && input.charCodeAt(pos + 1) === C.Slash) {\n\t\t\t\tpos += 2;\n\t\t\t\twhile (pos < length && input.charCodeAt(pos) !== C.Newline) {\n\t\t\t\t\tpos++;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tthis.pos = pos;\n\n\t\tif (pos >= this.length) {\n\t\t\treturn { type: \"EOF\", start: pos, end: pos };\n\t\t}\n\n\t\tconst code = input.charCodeAt(pos);\n\n\t\t// Single character tokens (most common first)\n\t\tswitch (code) {\n\t\t\tcase C.LParen:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"LPAREN\", start: pos, end: pos + 1 };\n\t\t\tcase C.RParen:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"RPAREN\", start: pos, end: pos + 1 };\n\t\t\tcase C.LBracket:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"LBRACKET\", start: pos, end: pos + 1 };\n\t\t\tcase C.RBracket:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"RBRACKET\", start: pos, end: pos + 1 };\n\t\t\tcase C.Comma:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"COMMA\", start: pos, end: pos + 1 };\n\t\t\tcase C.Question:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"QUESTION\", start: pos, end: pos + 1 };\n\t\t\tcase C.Equals:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"EQ\", start: pos, end: pos + 1 };\n\t\t\tcase C.Tilde:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"LIKE\", start: pos, end: pos + 1 };\n\t\t\tcase C.Colon:\n\t\t\t\tthis.pos = pos + 1;\n\t\t\t\treturn { type: \"COLON\", start: pos, end: pos + 1 };\n\t\t}\n\n\t\t// Two-character operators\n\t\tconst nextCode = pos + 1 < this.length ? input.charCodeAt(pos + 1) : 0;\n\n\t\tif (code === C.Bang) {\n\t\t\tif (nextCode === C.Equals) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"NEQ\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t\tif (nextCode === C.Colon) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"NOT_COLON\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t}\n\n\t\tif (code === C.GreaterThan) {\n\t\t\tif (nextCode === C.Equals) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"GTE\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t\tthis.pos = pos + 1;\n\t\t\treturn { type: \"GT\", start: pos, end: pos + 1 };\n\t\t}\n\n\t\tif (code === C.LessThan) {\n\t\t\tif (nextCode === C.Equals) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"LTE\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t\tthis.pos = pos + 1;\n\t\t\treturn { type: \"LT\", start: pos, end: pos + 1 };\n\t\t}\n\n\t\tif (code === C.Dot) {\n\t\t\tif (nextCode === C.Dot) {\n\t\t\t\tthis.pos = pos + 2;\n\t\t\t\treturn { type: \"DOTDOT\", start: pos, end: pos + 2 };\n\t\t\t}\n\t\t\tthis.pos = pos + 1;\n\t\t\treturn { type: \"DOT\", start: pos, end: pos + 1 };\n\t\t}\n\n\t\t// String literal\n\t\tif (code === C.Quote) {\n\t\t\treturn this.readString();\n\t\t}\n\n\t\t// Number\n\t\tif (code >= C.Zero && code <= C.Nine) {\n\t\t\treturn this.readNumber();\n\t\t}\n\t\tif (code === C.Minus && nextCode >= C.Zero && nextCode <= C.Nine) {\n\t\t\treturn this.readNumber();\n\t\t}\n\n\t\t// Identifier or keyword\n\t\tif (\n\t\t\t(code >= C.LowerA && code <= C.LowerZ) ||\n\t\t\t(code >= C.UpperA && code <= C.UpperZ) ||\n\t\t\tcode === C.Underscore\n\t\t) {\n\t\t\treturn this.readIdentifier();\n\t\t}\n\n\t\tthrow new LexerError(`Unexpected character: '${input[pos]}'`, pos);\n\t}\n}\n", | ||
| "/**\n * Recursive Descent Parser for Filtron\n * https://en.wikipedia.org/wiki/Recursive_descent_parser\n *\n * Grammar (in order of precedence, lowest to highest):\n *\n * Query = OrExpression\n * OrExpression = AndExpression (OR AndExpression)*\n * AndExpression = NotExpression (AND NotExpression)*\n * NotExpression = NOT NotExpression | PrimaryExpression\n * PrimaryExpression = '(' OrExpression ')' | FieldExpression\n * FieldExpression = FieldName ('?' | EXISTS | ComparisonOp Value RangeSuffix? | OneOfOp '[' Values ']')?\n * FieldName = IDENT ('.' IDENT)*\n * Value = STRING | NUMBER | BOOLEAN | DottedIdent\n * Values = Value (',' Value)*\n * RangeSuffix = '..' NUMBER\n */\n\nimport type {\n\tASTNode,\n\tValue,\n\tComparisonOperator,\n\tComparisonExpression,\n\tOneOfExpression,\n\tNotOneOfExpression,\n\tExistsExpression,\n\tBooleanFieldExpression,\n\tRangeExpression,\n} from \"./types\";\nimport { Lexer, type Token, type TokenType, type StringToken, type NumberToken } from \"./lexer\";\n\n/**\n * Parser error with position information\n */\nexport class ParseError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic position: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"ParseError\";\n\t}\n}\n\n/**\n * Parser for Filtron queries\n */\nclass Parser {\n\tprivate lexer: Lexer;\n\tprivate current: Token;\n\tprivate nextToken: Token | null = null;\n\n\tconstructor(input: string) {\n\t\tthis.lexer = new Lexer(input);\n\t\tthis.current = this.lexer.next();\n\t}\n\n\t/**\n\t * Advance to the next token and return the previous one\n\t */\n\tprivate advance(): Token {\n\t\tconst prev = this.current;\n\t\tif (this.nextToken) {\n\t\t\tthis.current = this.nextToken;\n\t\t\tthis.nextToken = null;\n\t\t} else {\n\t\t\tthis.current = this.lexer.next();\n\t\t}\n\t\treturn prev;\n\t}\n\n\t/**\n\t * Check if current token matches the given type\n\t */\n\tprivate check(type: TokenType): boolean {\n\t\treturn this.current.type === type;\n\t}\n\n\t/**\n\t * Consume a token of the expected type, or throw an error\n\t */\n\tprivate expect(type: TokenType, message?: string): Token {\n\t\tif (this.current.type !== type) {\n\t\t\tconst msg = message ?? `Expected ${type}, got ${this.current.type}`;\n\t\t\tthrow new ParseError(msg, this.current.start);\n\t\t}\n\t\treturn this.advance();\n\t}\n\n\t/**\n\t * Parse a complete query\n\t */\n\tparse(): ASTNode {\n\t\tif (this.check(\"EOF\")) {\n\t\t\tthrow new ParseError(\"Empty query\", 0);\n\t\t}\n\n\t\tconst result = this.parseOrExpression();\n\n\t\tif (!this.check(\"EOF\")) {\n\t\t\tthrow new ParseError(`Unexpected token: ${this.current.type}`, this.current.start);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Parse OR expression\n\t * OrExpression = AndExpression (OR AndExpression)*\n\t */\n\tprivate parseOrExpression(): ASTNode {\n\t\tlet left = this.parseAndExpression();\n\n\t\twhile (this.check(\"OR\")) {\n\t\t\tthis.advance();\n\t\t\tconst right = this.parseAndExpression();\n\t\t\tleft = { type: \"or\", left, right };\n\t\t}\n\n\t\treturn left;\n\t}\n\n\t/**\n\t * Parse AND expression\n\t * AndExpression = NotExpression (AND NotExpression)*\n\t */\n\tprivate parseAndExpression(): ASTNode {\n\t\tlet left = this.parseNotExpression();\n\n\t\twhile (this.check(\"AND\")) {\n\t\t\tthis.advance();\n\t\t\tconst right = this.parseNotExpression();\n\t\t\tleft = { type: \"and\", left, right };\n\t\t}\n\n\t\treturn left;\n\t}\n\n\t/**\n\t * Parse NOT expression\n\t * NotExpression = NOT NotExpression | PrimaryExpression\n\t */\n\tprivate parseNotExpression(): ASTNode {\n\t\tif (this.check(\"NOT\")) {\n\t\t\tthis.advance();\n\t\t\tconst expression = this.parseNotExpression();\n\t\t\treturn { type: \"not\", expression };\n\t\t}\n\n\t\treturn this.parsePrimaryExpression();\n\t}\n\n\t/**\n\t * Parse primary expression (highest precedence)\n\t * PrimaryExpression = '(' OrExpression ')' | FieldExpression\n\t */\n\tprivate parsePrimaryExpression(): ASTNode {\n\t\t// Parenthesized expression\n\t\tif (this.check(\"LPAREN\")) {\n\t\t\tthis.advance();\n\t\t\tconst expr = this.parseOrExpression();\n\t\t\tthis.expect(\"RPAREN\", \"Expected closing parenthesis\");\n\t\t\treturn expr;\n\t\t}\n\n\t\treturn this.parseFieldExpression();\n\t}\n\n\t/**\n\t * Parse field expression\n\t * FieldExpression = FieldName ('?' | EXISTS | ComparisonOp Value RangeSuffix? | OneOfOp '[' Values ']')?\n\t */\n\tprivate parseFieldExpression(): ASTNode {\n\t\tconst field = this.parseFieldName();\n\t\tconst t = this.current.type;\n\n\t\t// Exists check with ? or EXISTS\n\t\tif (t === \"QUESTION\" || t === \"EXISTS\") {\n\t\t\tthis.advance();\n\t\t\treturn { type: \"exists\", field } as ExistsExpression;\n\t\t}\n\n\t\t// OneOf: field : [values]\n\t\tif (t === \"COLON\" && this.peekNextIsLBracket()) {\n\t\t\tthis.advance();\n\t\t\treturn this.parseOneOfArray(field, \"oneOf\");\n\t\t}\n\n\t\t// NotOneOf: field !: [values]\n\t\tif (t === \"NOT_COLON\") {\n\t\t\tthis.advance();\n\t\t\treturn this.parseOneOfArray(field, \"notOneOf\");\n\t\t}\n\n\t\t// Comparison with operator\n\t\tif (\n\t\t\tt === \"EQ\" ||\n\t\t\tt === \"NEQ\" ||\n\t\t\tt === \"GT\" ||\n\t\t\tt === \"GTE\" ||\n\t\t\tt === \"LT\" ||\n\t\t\tt === \"LTE\" ||\n\t\t\tt === \"LIKE\" ||\n\t\t\tt === \"COLON\"\n\t\t) {\n\t\t\tconst opToken = this.advance();\n\t\t\tconst operator = this.tokenToOperator(opToken);\n\n\t\t\t// Check for range expression: field = min..max\n\t\t\tif (operator === \"=\" && this.check(\"NUMBER\")) {\n\t\t\t\tconst minToken = this.advance() as NumberToken;\n\t\t\t\tconst min = minToken.value;\n\n\t\t\t\tif (this.check(\"DOTDOT\")) {\n\t\t\t\t\tthis.advance();\n\t\t\t\t\tconst maxToken = this.expect(\"NUMBER\", \"Expected number after '..'\") as NumberToken;\n\t\t\t\t\tconst max = maxToken.value;\n\t\t\t\t\treturn { type: \"range\", field, min, max } as RangeExpression;\n\t\t\t\t}\n\n\t\t\t\t// Not a range, just a regular comparison with a number\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"comparison\",\n\t\t\t\t\tfield,\n\t\t\t\t\toperator,\n\t\t\t\t\tvalue: { type: \"number\", value: min },\n\t\t\t\t} as ComparisonExpression;\n\t\t\t}\n\n\t\t\tconst value = this.parseValue();\n\t\t\treturn {\n\t\t\t\ttype: \"comparison\",\n\t\t\t\tfield,\n\t\t\t\toperator,\n\t\t\t\tvalue,\n\t\t\t} as ComparisonExpression;\n\t\t}\n\n\t\t// Boolean field shorthand (just the field name)\n\t\treturn { type: \"booleanField\", field } as BooleanFieldExpression;\n\t}\n\n\t/**\n\t * Check if the token after the current one is LBRACKET\n\t * (used to distinguish : as oneOf vs : as comparison operator)\n\t */\n\tprivate peekNextIsLBracket(): boolean {\n\t\tif (!this.nextToken) {\n\t\t\tthis.nextToken = this.lexer.next();\n\t\t}\n\t\treturn this.nextToken.type === \"LBRACKET\";\n\t}\n\n\t/**\n\t * Convert a token to its corresponding comparison operator\n\t */\n\tprivate tokenToOperator(token: Token): ComparisonOperator {\n\t\tswitch (token.type) {\n\t\t\tcase \"EQ\":\n\t\t\t\treturn \"=\";\n\t\t\tcase \"NEQ\":\n\t\t\t\treturn \"!=\";\n\t\t\tcase \"GT\":\n\t\t\t\treturn \">\";\n\t\t\tcase \"GTE\":\n\t\t\t\treturn \">=\";\n\t\t\tcase \"LT\":\n\t\t\t\treturn \"<\";\n\t\t\tcase \"LTE\":\n\t\t\t\treturn \"<=\";\n\t\t\tcase \"LIKE\":\n\t\t\t\treturn \"~\";\n\t\t\tcase \"COLON\":\n\t\t\t\treturn \":\";\n\t\t\tdefault:\n\t\t\t\tthrow new ParseError(`Invalid operator: ${token.type}`, token.start);\n\t\t}\n\t}\n\n\t/**\n\t * Parse a field name (possibly dotted)\n\t * FieldName = IDENT ('.' IDENT)*\n\t */\n\tprivate parseFieldName(): string {\n\t\tconst first = this.expect(\"IDENT\", \"Expected field name\") as StringToken;\n\t\tlet name = first.value;\n\n\t\twhile (this.check(\"DOT\")) {\n\t\t\tthis.advance(); // consume .\n\t\t\tconst next = this.expect(\"IDENT\", \"Expected identifier after '.'\") as StringToken;\n\t\t\tname += \".\" + next.value;\n\t\t}\n\n\t\treturn name;\n\t}\n\n\t/**\n\t * Parse oneOf/notOneOf array\n\t * '[' Values ']'\n\t */\n\tprivate parseOneOfArray(\n\t\tfield: string,\n\t\ttype: \"oneOf\" | \"notOneOf\",\n\t): OneOfExpression | NotOneOfExpression {\n\t\tthis.expect(\"LBRACKET\", \"Expected '[' after operator\");\n\n\t\tconst values: Value[] = [];\n\n\t\t// Handle non-empty array\n\t\tif (!this.check(\"RBRACKET\")) {\n\t\t\tvalues.push(this.parseValue());\n\n\t\t\twhile (this.check(\"COMMA\")) {\n\t\t\t\tthis.advance(); // consume ,\n\t\t\t\tvalues.push(this.parseValue());\n\t\t\t}\n\t\t}\n\n\t\tthis.expect(\"RBRACKET\", \"Expected ']' to close array\");\n\n\t\tif (values.length === 0) {\n\t\t\tthrow new ParseError(\"Array cannot be empty\", this.current.start);\n\t\t}\n\n\t\treturn { type, field, values };\n\t}\n\n\t/**\n\t * Parse a value\n\t * Value = STRING | NUMBER | BOOLEAN | DottedIdent\n\t */\n\tprivate parseValue(): Value {\n\t\tconst t = this.current.type;\n\n\t\t// String literal\n\t\tif (t === \"STRING\") {\n\t\t\tconst token = this.advance() as StringToken;\n\t\t\treturn { type: \"string\", value: token.value };\n\t\t}\n\n\t\t// Number literal\n\t\tif (t === \"NUMBER\") {\n\t\t\tconst token = this.advance() as NumberToken;\n\t\t\treturn { type: \"number\", value: token.value };\n\t\t}\n\n\t\t// Boolean literal\n\t\tif (t === \"TRUE\") {\n\t\t\tthis.advance();\n\t\t\treturn { type: \"boolean\", value: true };\n\t\t}\n\t\tif (t === \"FALSE\") {\n\t\t\tthis.advance();\n\t\t\treturn { type: \"boolean\", value: false };\n\t\t}\n\n\t\t// Identifier (possibly dotted)\n\t\tif (t === \"IDENT\") {\n\t\t\tconst first = this.advance() as StringToken;\n\t\t\tlet value = first.value;\n\n\t\t\twhile (this.check(\"DOT\")) {\n\t\t\t\tthis.advance(); // consume .\n\t\t\t\tconst next = this.expect(\"IDENT\", \"Expected identifier after '.'\") as StringToken;\n\t\t\t\tvalue += \".\" + next.value;\n\t\t\t}\n\n\t\t\treturn { type: \"identifier\", value };\n\t\t}\n\n\t\tthrow new ParseError(`Expected value, got ${t}`, this.current.start);\n\t}\n}\n\n/**\n * Parse a Filtron query string into an AST\n *\n * @param input - The query string to parse\n * @returns The parsed AST\n * @throws ParseError if the query is invalid\n */\nexport function parseQuery(input: string): ASTNode {\n\tconst parser = new Parser(input);\n\treturn parser.parse();\n}\n", | ||
| "/**\n * The Filtron parser public API\n */\n\nimport type { ASTNode } from \"./types\";\nimport { LexerError } from \"./lexer\";\nimport { parseQuery, ParseError as RDParseError } from \"./rd-parser\";\n\n/**\n * Error thrown by parseOrThrow when parsing fails.\n * Includes the position in the query where the error occurred.\n */\nexport class FiltronParseError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic position?: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"FiltronParseError\";\n\t}\n}\n\n/**\n * Result of a successful parse operation\n */\nexport interface ParseSuccess {\n\tsuccess: true;\n\tast: ASTNode;\n}\n\n/**\n * Result of a failed parse operation\n */\nexport interface ParseError {\n\tsuccess: false;\n\terror: string;\n\tmessage: string;\n\tposition?: number;\n}\n\n/**\n * The generic parse result\n */\nexport type ParseResult = ParseSuccess | ParseError;\n\n/**\n * Parses a Filtron query string into an Abstract Syntax Tree (AST).\n *\n * @param query - The Filtron query string to parse\n * @returns A ParseResult containing either the AST or an error\n *\n * @example\n * ```typescript\n * const result = parse('age > 18 AND status = \"active\"');\n * if (result.success) {\n * console.log(result.ast);\n * } else {\n * console.error(result.error);\n * }\n * ```\n */\nexport const parse = (query: string): ParseResult => {\n\ttry {\n\t\tconst ast = parseQuery(query);\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tast,\n\t\t};\n\t} catch (error) {\n\t\tlet message: string;\n\t\tlet position: number | undefined;\n\n\t\tif (error instanceof RDParseError || error instanceof LexerError) {\n\t\t\tmessage = error.message;\n\t\t\tposition = error.position;\n\t\t} else if (error instanceof Error) {\n\t\t\tmessage = error.message;\n\t\t} else {\n\t\t\tmessage = String(error);\n\t\t}\n\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: message,\n\t\t\tmessage,\n\t\t\tposition,\n\t\t};\n\t}\n};\n\n/**\n * Parses a Filtron query string and throws an error if parsing fails.\n * Use this when you want to handle errors with try/catch instead of checking the result.\n *\n * @param query - The Filtron query string to parse\n * @returns The parsed AST\n * @throws FiltronParseError if parsing fails, with position information\n *\n * @example\n * ```typescript\n * try {\n * const ast = parseOrThrow('age > 18');\n * console.log(ast);\n * } catch (error) {\n * if (error instanceof FiltronParseError) {\n * console.error('Parse failed at position', error.position, ':', error.message);\n * }\n * }\n * ```\n */\nexport const parseOrThrow = (query: string): ASTNode => {\n\tconst result = parse(query);\n\n\tif (result.success) {\n\t\treturn result.ast;\n\t}\n\n\tthrow new FiltronParseError(`Failed to parse Filtron query: ${result.error}`, result.position);\n};\n" | ||
| ], | ||
| "mappings": "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", | ||
| "debugId": "55F7033D8A7F4FE964756E2164756E21", | ||
| "mappings": "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", | ||
| "debugId": "2694F8F687E1664164756E2164756E21", | ||
| "names": [] | ||
| } |
@@ -17,4 +17,4 @@ /** | ||
| export { Lexer, LexerError } from "./lexer"; | ||
| export type { Token, TokenType, StringToken, NumberToken, BooleanToken } from "./lexer"; | ||
| export type { Token, TokenType, StringToken, NumberToken, BooleanToken, SymbolToken, } from "./lexer"; | ||
| export type { ASTNode, Value, ComparisonOperator, OrExpression, AndExpression, NotExpression, ComparisonExpression, OneOfExpression, NotOneOfExpression, ExistsExpression, BooleanFieldExpression, RangeExpression, StringValue, NumberValue, BooleanValue, IdentifierValue, } from "./types"; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGxF,YAAY,EACX,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,GACf,MAAM,SAAS,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EACX,KAAK,EACL,SAAS,EACT,WAAW,EACX,WAAW,EACX,YAAY,EACZ,WAAW,GACX,MAAM,SAAS,CAAC;AAGjB,YAAY,EACX,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,GACf,MAAM,SAAS,CAAC"} |
@@ -13,7 +13,11 @@ /** | ||
| } | ||
| /** Tokens with string values (punctuation, operators, keywords, identifiers) */ | ||
| /** Tokens with string values (string literals and identifiers) */ | ||
| export interface StringToken extends TokenBase { | ||
| type: "LPAREN" | "RPAREN" | "LBRACKET" | "RBRACKET" | "COMMA" | "QUESTION" | "DOT" | "DOTDOT" | "AND" | "OR" | "NOT" | "EXISTS" | "EQ" | "NEQ" | "GT" | "GTE" | "LT" | "LTE" | "LIKE" | "COLON" | "NOT_COLON" | "STRING" | "IDENT" | "EOF"; | ||
| type: "STRING" | "IDENT"; | ||
| value: string; | ||
| } | ||
| /** Tokens without values (operators, punctuation, keywords, EOF) */ | ||
| export interface SymbolToken extends TokenBase { | ||
| type: "LPAREN" | "RPAREN" | "LBRACKET" | "RBRACKET" | "COMMA" | "QUESTION" | "DOT" | "DOTDOT" | "AND" | "OR" | "NOT" | "EXISTS" | "EQ" | "NEQ" | "GT" | "GTE" | "LT" | "LTE" | "LIKE" | "COLON" | "NOT_COLON" | "EOF"; | ||
| } | ||
| /** Tokens with number values */ | ||
@@ -32,3 +36,3 @@ export interface NumberToken extends TokenBase { | ||
| */ | ||
| export type Token = StringToken | NumberToken | BooleanToken; | ||
| export type Token = StringToken | NumberToken | BooleanToken | SymbolToken; | ||
| /** | ||
@@ -35,0 +39,0 @@ * Lexer error with position information |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/lexer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,SAAS,GAClB,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,UAAU,GACV,OAAO,GACP,UAAU,GACV,KAAK,GACL,QAAQ,GACR,KAAK,GACL,IAAI,GACJ,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,MAAM,GACN,OAAO,GACP,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,KAAK,CAAC;AAET,4BAA4B;AAC5B,UAAU,SAAS;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,gFAAgF;AAChF,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC7C,IAAI,EACD,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,UAAU,GACV,OAAO,GACP,UAAU,GACV,KAAK,GACL,QAAQ,GACR,KAAK,GACL,IAAI,GACJ,KAAK,GACL,QAAQ,GACR,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,MAAM,GACN,OAAO,GACP,WAAW,GACX,QAAQ,GACR,OAAO,GACP,KAAK,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACd;AAED,gCAAgC;AAChC,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC7C,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC9C,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AAqC7D;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;IAG5B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM;CAKxB;AAED;;GAEG;AACH,qBAAa,KAAK;IACjB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,KAAK,EAAE,MAAM;IAKzB;;OAEG;IACH,OAAO,CAAC,UAAU;IA8ElB;;OAEG;IACH,OAAO,CAAC,UAAU;IAwDlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAiGtB;;OAEG;IACH,IAAI,IAAI,KAAK;CA4Hb"} | ||
| {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/lexer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,SAAS,GAClB,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,UAAU,GACV,OAAO,GACP,UAAU,GACV,KAAK,GACL,QAAQ,GACR,KAAK,GACL,IAAI,GACJ,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,MAAM,GACN,OAAO,GACP,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,KAAK,CAAC;AAET,4BAA4B;AAC5B,UAAU,SAAS;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,kEAAkE;AAClE,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC7C,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,oEAAoE;AACpE,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC7C,IAAI,EACD,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,UAAU,GACV,OAAO,GACP,UAAU,GACV,KAAK,GACL,QAAQ,GACR,KAAK,GACL,IAAI,GACJ,KAAK,GACL,QAAQ,GACR,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,IAAI,GACJ,KAAK,GACL,MAAM,GACN,OAAO,GACP,WAAW,GACX,KAAK,CAAC;CACT;AAED,gCAAgC;AAChC,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC7C,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC9C,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,KAAK,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,CAAC;AAqC3E;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;IAG5B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM;CAKxB;AAED;;GAEG;AACH,qBAAa,KAAK;IACjB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,KAAK,EAAE,MAAM;IAKzB;;OAEG;IACH,OAAO,CAAC,UAAU;IA8ElB;;OAEG;IACH,OAAO,CAAC,UAAU;IAwDlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAiGtB;;OAEG;IACH,IAAI,IAAI,KAAK;CA4Hb"} |
+4
-4
| { | ||
| "$schema": "https://json.schemastore.org/package.json", | ||
| "name": "@filtron/core", | ||
| "version": "1.4.0", | ||
| "version": "2.0.0", | ||
| "description": "Filtron parses human-friendly filter strings into structured queries you can use anywhere — SQL databases, in-memory arrays, or your own custom backend.", | ||
@@ -49,3 +49,3 @@ "keywords": [ | ||
| "bench": "bun run build && bun --expose-gc run benchmark.ts", | ||
| "build": "bun build --production --splitting --sourcemap=linked --outdir=dist index.ts && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist --skipLibCheck", | ||
| "build": "bun build --production --splitting --sourcemap=linked --metafile=metafile.json --outdir=dist index.ts && tsc --emitDeclarationOnly --declaration --declarationMap --outDir dist --skipLibCheck", | ||
| "prepublishOnly": "bun run build && bun test", | ||
@@ -57,3 +57,3 @@ "test": "bun test", | ||
| "@filtron/benchmark": "1.0.0", | ||
| "@types/bun": "1.3.6", | ||
| "@types/bun": "1.3.8", | ||
| "typescript": "5.9.3" | ||
@@ -73,3 +73,3 @@ }, | ||
| }, | ||
| "packageManager": "bun@1.3.6" | ||
| "packageManager": "bun@1.3.8" | ||
| } |
493
0.61%72051
-0.45%