22
33var util = require ( 'util' ) ;
44
5- var re4Integer = '-?(?:0|[1-9][0-9]*)' ;
5+ var re = exports . re = ( function ( ) {
6+ var re4Integer = '-?(?:0|[1-9][0-9]*)' ;
67
7- var re = exports . re = {
8- identifier : new RegExp ( '^[a-zA-Z_\\$]+[a-zA-Z0-9_]*' ) ,
9- integer : new RegExp ( re4Integer ) ,
10- range : new RegExp ( util . format ( '^(%s)?\\:(%s)?(?:\\:(%s)?)?' , re4Integer , re4Integer , re4Integer ) ) ,
11- q_string : new RegExp ( '^\'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*\'' ) ,
12- qq_string : new RegExp ( '^\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"' )
8+ return {
9+ identifier : new RegExp ( '^[a-zA-Z_\\$]+[a-zA-Z0-9_]*' ) ,
10+ integer : new RegExp ( re4Integer ) ,
11+ range : new RegExp ( util . format ( '^(%s)?\\:(%s)?(?:\\:(%s)?)?' , re4Integer , re4Integer , re4Integer ) ) ,
12+ q_string : new RegExp ( '^\'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*\'' ) ,
13+ qq_string : new RegExp ( '^\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"' )
14+ } ;
15+ } ) ( ) ;
16+
17+ var _n = exports . _n = function ( type ) {
18+ return {
19+ type : type
20+ } ;
1321} ;
1422
15- var types = {
16- ROOT : {
17- type : 'root'
18- } ,
19- WILDCARD : {
20- type : 'wildcard'
21- } ,
22- RECURSIVE_DESCENT : {
23- type : 'recursive_descent'
24- } ,
25- PARENT : {
26- type : 'parent'
27- }
23+ var _p = exports . _p = function ( property ) {
24+ return {
25+ type : 'property' ,
26+ parameter : property
27+ } ;
2828} ;
2929
30- var propertyUpdate = {
31- identifier : function ( properties , reExecResult ) {
32- properties . push ( reExecResult [ 0 ] ) ;
33- } ,
34- integer : function ( properties , reExecResult ) {
35- var i = parseInt ( reExecResult [ 0 ] , 10 ) ;
36- properties . push ( i ) ;
37- } ,
38- q_string : function ( properties , reExecResult ) {
39- var r = reExecResult [ 0 ] ;
40- properties . push ( r . substring ( 1 , r . length - 1 ) ) ;
41- } ,
42- qq_string : function ( properties , reExecResult ) {
43- var r = reExecResult [ 0 ] ;
44- properties . push ( r . substring ( 1 , r . length - 1 ) ) ;
45- } ,
46- range : function ( properties , reExecResult ) {
47- var start = ( reExecResult [ 1 ] && parseInt ( reExecResult [ 1 ] , 10 ) ) || 0 ;
48- var end = ( reExecResult [ 2 ] && parseInt ( reExecResult [ 2 ] , 10 ) ) || null ;
49- var step = ( reExecResult [ 3 ] && parseInt ( reExecResult [ 3 ] , 10 ) ) || 1 ;
50- properties . push ( {
51- start : start ,
52- end : end ,
53- step : step
54- } ) ;
55- }
30+ var _fn = exports . _fn = function ( fn ) {
31+ return {
32+ type : 'fn' ,
33+ parameter : fn
34+ } ;
5635} ;
5736
58- var expandSubscriptProperties = exports . expandSubscriptProperties = function expandSubscriptProperties ( subscript , properties ) {
59- var reKeys = [ 'range' , 'identifier' , 'integer' , 'q_string' , 'qq_string' ] ;
60- var n = reKeys . length ;
61- for ( var i = 0 ; i < n ; ++ i ) {
62- var key = reKeys [ i ] ;
63- var r = re [ key ] ;
64- var result = r . exec ( subscript ) ;
65- if ( result ) {
66- propertyUpdate [ key ] ( properties , result ) ;
67- var nResult = result [ 0 ] . length ;
68- if ( nResult === subscript . length ) {
69- return true ;
70- }
71- if ( subscript [ nResult ] !== ',' ) {
72- var msg = util . format ( 'Invalid character "%s" in %s.' , subscript [ nResult ] , subscript ) ;
73- throw new Error ( msg ) ;
74- }
75- subscript = subscript . substring ( nResult + 1 ) ;
76- return expandSubscriptProperties ( subscript , properties ) ;
77- }
78- }
79- return false ;
37+ var _ps = exports . _ps = function ( properties ) {
38+ return {
39+ type : 'properties' ,
40+ parameter : properties
41+ } ;
42+ } ;
43+
44+ var _sp = exports . _sp = function ( path ) {
45+ return {
46+ type : 'subpath' ,
47+ parameter : path
48+ } ;
49+ } ;
50+
51+ var _scr = exports . _scr = function ( script ) {
52+ return {
53+ type : 'script' ,
54+ parameter : script
55+ } ;
56+ } ;
57+
58+ var _fil = exports . _fil = function ( script ) {
59+ return {
60+ type : 'filter_script' ,
61+ parameter : script
62+ } ;
8063} ;
8164
82- var subscriptHandlers = {
83- '$' : {
84- verify : function ( subscript ) {
85- return ( subscript . length > 1 ) && ( subscript . charAt ( 1 ) === '.' ) ;
65+ var subscriptToNode = exports . subscriptToNode = ( function ( ) {
66+ var updateProperties = {
67+ identifier : function ( properties , reExecResult ) {
68+ properties . push ( reExecResult [ 0 ] ) ;
8669 } ,
87- node : function ( subscript ) {
88- return {
89- type : 'subpath' ,
90- parameter : subscript
91- } ;
70+ integer : function ( properties , reExecResult ) {
71+ var i = parseInt ( reExecResult [ 0 ] , 10 ) ;
72+ properties . push ( i ) ;
73+ } ,
74+ q_string : function ( properties , reExecResult ) {
75+ var r = reExecResult [ 0 ] ;
76+ properties . push ( r . substring ( 1 , r . length - 1 ) ) ;
77+ } ,
78+ qq_string : function ( properties , reExecResult ) {
79+ var r = reExecResult [ 0 ] ;
80+ properties . push ( r . substring ( 1 , r . length - 1 ) ) ;
81+ } ,
82+ range : function ( properties , reExecResult ) {
83+ var start = ( reExecResult [ 1 ] && parseInt ( reExecResult [ 1 ] , 10 ) ) || 0 ;
84+ var end = ( reExecResult [ 2 ] && parseInt ( reExecResult [ 2 ] , 10 ) ) || null ;
85+ var step = ( reExecResult [ 3 ] && parseInt ( reExecResult [ 3 ] , 10 ) ) || 1 ;
86+ properties . push ( {
87+ start : start ,
88+ end : end ,
89+ step : step
90+ } ) ;
9291 }
93- } ,
94- '?' : {
95- verify : function ( subscript ) {
96- var n = subscript . length ;
97- if ( ( n < 2 ) || ( subscript . charAt ( 1 ) !== '(' ) ) {
98- throw new Error ( 'Subscript start with "?" but the second character is not "("' ) ;
92+ } ;
93+
94+ var extractListableProperties = exports . extractListableProperties = function extractListableProperties ( subscript , properties ) {
95+ var reKeys = [ 'range' , 'identifier' , 'integer' , 'q_string' , 'qq_string' ] ;
96+ var n = reKeys . length ;
97+ for ( var i = 0 ; i < n ; ++ i ) {
98+ var key = reKeys [ i ] ;
99+ var r = re [ key ] ;
100+ var result = r . exec ( subscript ) ;
101+ if ( result ) {
102+ updateProperties [ key ] ( properties , result ) ;
103+ var nResult = result [ 0 ] . length ;
104+ if ( nResult === subscript . length ) {
105+ return true ;
106+ }
107+ if ( subscript [ nResult ] !== ',' ) {
108+ var msg = util . format ( 'Invalid character "%s" in %s.' , subscript [ nResult ] , subscript ) ;
109+ throw new Error ( msg ) ;
110+ }
111+ subscript = subscript . substring ( nResult + 1 ) ;
112+ return extractListableProperties ( subscript , properties ) ;
99113 }
100- if ( subscript . charAt ( n - 1 ) !== ')' ) {
101- throw new Error ( 'Subscript starts with "?(" but does not end with ")".' ) ;
114+ }
115+ return false ;
116+ } ;
117+
118+ var subscriptSpecialHandlers = {
119+ '$' : {
120+ verify : function ( subscript ) {
121+ return ( subscript . length > 1 ) && ( subscript . charAt ( 1 ) === '.' ) ;
122+ } ,
123+ node : function ( subscript ) {
124+ return _sp ( subscript ) ;
102125 }
103- return true ;
104126 } ,
105- node : function ( subscript ) {
106- var n = subscript . length ;
107- return {
108- type : 'filter_script' ,
109- parameter : subscript . substring ( 2 , n - 1 )
110- } ;
111- }
112- } ,
113- '(' : {
114- verify : function ( subscript ) {
115- var n = subscript . length ;
116- if ( subscript . charAt ( n - 1 ) !== ')' ) {
117- throw new Error ( 'Subscript starts with "(" but does not end with ")".' ) ;
127+ '?' : {
128+ verify : function ( subscript ) {
129+ var n = subscript . length ;
130+ if ( ( n < 2 ) || ( subscript . charAt ( 1 ) !== '(' ) ) {
131+ throw new Error ( 'Subscript start with "?" but the second character is not "("' ) ;
132+ }
133+ if ( subscript . charAt ( n - 1 ) !== ')' ) {
134+ throw new Error ( 'Subscript starts with "?(" but does not end with ")".' ) ;
135+ }
136+ return true ;
137+ } ,
138+ node : function ( subscript ) {
139+ var n = subscript . length ;
140+ return _fil ( subscript . substring ( 2 , n - 1 ) ) ;
118141 }
119- return true ;
120142 } ,
121- node : function ( subscript ) {
122- var n = subscript . length ;
123- return {
124- type : 'script' ,
125- parameter : subscript . substring ( 1 , n - 1 )
126- } ;
127- }
128- } ,
129- '*' : {
130- verify : function ( subscript ) {
131- return subscript . length === 1 ;
143+ '(' : {
144+ verify : function ( subscript ) {
145+ var n = subscript . length ;
146+ if ( subscript . charAt ( n - 1 ) !== ')' ) {
147+ throw new Error ( 'Subscript starts with "(" but does not end with ")".' ) ;
148+ }
149+ return true ;
150+ } ,
151+ node : function ( subscript ) {
152+ var n = subscript . length ;
153+ return _scr ( subscript . substring ( 1 , n - 1 ) ) ;
154+ }
132155 } ,
133- node : function ( subscript ) {
134- return types . WILDCARD ;
156+ '*' : {
157+ verify : function ( subscript ) {
158+ return subscript . length === 1 ;
159+ } ,
160+ node : function ( subscript ) {
161+ return _n ( 'wildcard' ) ;
162+ }
135163 }
136- }
137- } ;
164+ } ;
138165
139- var subscriptToNode = function ( subscript ) {
140- if ( subscript . length === 0 ) {
141- throw new Error ( 'Empty subscript in path.' ) ;
142- }
166+ return function ( subscript ) {
167+ if ( subscript . length === 0 ) {
168+ throw new Error ( 'Empty subscript in path.' ) ;
169+ }
143170
144- var c = subscript . charAt ( 0 ) ;
145- var handler = subscriptHandlers [ c ] ;
146- if ( handler && handler . verify ( subscript ) ) {
147- return handler . node ( subscript ) ;
148- }
171+ var c = subscript . charAt ( 0 ) ;
172+ var handler = subscriptSpecialHandlers [ c ] ;
173+ if ( handler && handler . verify ( subscript ) ) {
174+ return handler . node ( subscript ) ;
175+ }
149176
150- var properties = [ ] ;
151- var result = expandSubscriptProperties ( subscript , properties ) ;
152- if ( result ) {
153- var single = ( properties . length === 1 ) && ( typeof properties [ 0 ] !== 'object' ) ;
154- return {
155- type : single ? 'property' : 'properties' ,
156- parameter : single ? properties [ 0 ] : properties
157- } ;
158- }
177+ var properties = [ ] ;
178+ var result = extractListableProperties ( subscript , properties ) ;
179+ if ( result ) {
180+ var single = ( properties . length === 1 ) && ( typeof properties [ 0 ] !== 'object' ) ;
181+ if ( single ) {
182+ return _p ( properties [ 0 ] ) ;
183+ } else {
184+ return _ps ( properties ) ;
185+ }
186+ }
159187
160- throw new Error ( 'Invalid subscript: ' + subscript ) ;
161- } ;
188+ throw new Error ( 'Invalid subscript: ' + subscript ) ;
189+ } ;
190+ } ) ( ) ;
162191
163192var findClosingSquareBracket = function ( path , index ) {
164193 var length = path . length ;
@@ -208,7 +237,7 @@ var nodeAccumulator = (function () {
208237 update : function ( a ) {
209238 a . startChild ( ) ;
210239 if ( a . char ( ) === '.' ) {
211- a . pushNode ( types . RECURSIVE_DESCENT ) ;
240+ a . pushNode ( _n ( 'recursive_descent' ) ) ;
212241 }
213242 }
214243 } ,
@@ -228,15 +257,15 @@ var nodeAccumulator = (function () {
228257 return a . lastIndex === a . index ;
229258 } ,
230259 update : function ( a ) {
231- a . pushNode ( types . WILDCARD ) ;
260+ a . pushNode ( _n ( 'wildcard' ) ) ;
232261 }
233262 } ,
234263 '$' : {
235264 verify : function ( a ) {
236265 return ( a . index === 0 ) && ( a . nextChar ( ) === '.' ) ;
237266 } ,
238267 update : function ( a ) {
239- a . pushNode ( types . ROOT ) ;
268+ a . pushNode ( _n ( 'root' ) ) ;
240269 }
241270 } ,
242271 '^' : {
@@ -245,7 +274,7 @@ var nodeAccumulator = (function () {
245274 } ,
246275 update : function ( a ) {
247276 a . clearPropertyBuffer ( ) ;
248- a . pushNode ( types . PARENT ) ;
277+ a . pushNode ( _n ( 'parent' ) ) ;
249278 }
250279 }
251280 } ;
@@ -268,16 +297,13 @@ var nodeAccumulator = (function () {
268297 clearPropertyBuffer : function ( ) {
269298 if ( this . lastIndex < this . index ) {
270299 var property = this . path . substring ( this . lastIndex , this . index ) ;
271- var type = 'property' ;
272300 var n = property . length ;
273301 if ( property . substring ( n - 2 , n ) === '()' ) {
274- type = 'fn' ;
275- property = property . substring ( 0 , n - 2 ) ;
302+ var fn = property . substring ( 0 , n - 2 ) ;
303+ this . nodes . push ( _fn ( fn ) ) ;
304+ } else {
305+ this . nodes . push ( _p ( property ) ) ;
276306 }
277- this . nodes . push ( {
278- type : type ,
279- parameter : property
280- } ) ;
281307 }
282308 } ,
283309 startChild : function ( ) {
0 commit comments