1
- function Lexer ( text , parsStrings ) {
2
- this . text = text ;
3
- // UTC dates have 20 characters, we send them through parser
4
- this . dateParseLength = parsStrings ? 20 : - 1 ;
5
- this . tokens = [ ] ;
6
- this . index = 0 ;
7
- }
8
-
9
1
OPERATORS = {
10
2
'null' :function ( self ) { return _null ; } ,
11
3
'true' :function ( self ) { return true ; } ,
@@ -33,143 +25,133 @@ OPERATORS = {
33
25
} ;
34
26
ESCAPE = { "n" :"\n" , "f" :"\f" , "r" :"\r" , "t" :"\t" , "v" :"\v" , "'" :"'" , '"' :'"' } ;
35
27
36
- Lexer . prototype = {
37
- peek : function ( ) {
38
- if ( this . index + 1 < this . text . length ) {
39
- return this . text . charAt ( this . index + 1 ) ;
28
+ function lex ( text , parseStrings ) {
29
+ var dateParseLength = parseStrings ? 20 : - 1 ,
30
+ tokens = [ ] ,
31
+ index = 0 ,
32
+ canStartRegExp = true ;
33
+
34
+ while ( index < text . length ) {
35
+ var ch = text . charAt ( index ) ;
36
+ if ( ch == '"' || ch == "'" ) {
37
+ readString ( ch ) ;
38
+ canStartRegExp = true ;
39
+ } else if ( ch == '(' || ch == '[' ) {
40
+ tokens . push ( { index :index , text :ch } ) ;
41
+ index ++ ;
42
+ } else if ( ch == '{' ) {
43
+ var peekCh = peek ( ) ;
44
+ if ( peekCh == ':' || peekCh == '(' ) {
45
+ tokens . push ( { index :index , text :ch + peekCh } ) ;
46
+ index ++ ;
47
+ } else {
48
+ tokens . push ( { index :index , text :ch } ) ;
49
+ }
50
+ index ++ ;
51
+ canStartRegExp = true ;
52
+ } else if ( ch == ')' || ch == ']' || ch == '}' ) {
53
+ tokens . push ( { index :index , text :ch } ) ;
54
+ index ++ ;
55
+ canStartRegExp = false ;
56
+ } else if ( ch == ':' || ch == '.' || ch == ',' || ch == ';' ) {
57
+ tokens . push ( { index :index , text :ch } ) ;
58
+ index ++ ;
59
+ canStartRegExp = true ;
60
+ } else if ( canStartRegExp && ch == '/' ) {
61
+ readRegexp ( ) ;
62
+ canStartRegExp = false ;
63
+ } else if ( isNumber ( ch ) ) {
64
+ readNumber ( ) ;
65
+ canStartRegExp = false ;
66
+ } else if ( isIdent ( ch ) ) {
67
+ readIdent ( ) ;
68
+ canStartRegExp = false ;
69
+ } else if ( isWhitespace ( ch ) ) {
70
+ index ++ ;
40
71
} else {
41
- return false ;
42
- }
43
- } ,
44
-
45
- parse : function ( ) {
46
- var tokens = this . tokens ;
47
- var canStartRegExp = true ;
48
- while ( this . index < this . text . length ) {
49
- var ch = this . text . charAt ( this . index ) ;
50
- if ( ch == '"' || ch == "'" ) {
51
- this . readString ( ch ) ;
52
- canStartRegExp = true ;
53
- } else if ( ch == '(' || ch == '[' ) {
54
- tokens . push ( { index :this . index , text :ch } ) ;
55
- this . index ++ ;
56
- } else if ( ch == '{' ) {
57
- var peekCh = this . peek ( ) ;
58
- if ( peekCh == ':' || peekCh == '(' ) {
59
- tokens . push ( { index :this . index , text :ch + peekCh } ) ;
60
- this . index ++ ;
61
- } else {
62
- tokens . push ( { index :this . index , text :ch } ) ;
63
- }
64
- this . index ++ ;
65
- canStartRegExp = true ;
66
- } else if ( ch == ')' || ch == ']' || ch == '}' ) {
67
- tokens . push ( { index :this . index , text :ch } ) ;
68
- this . index ++ ;
69
- canStartRegExp = false ;
70
- } else if ( ch == ':' || ch == '.' || ch == ',' || ch == ';' ) {
71
- tokens . push ( { index :this . index , text :ch } ) ;
72
- this . index ++ ;
73
- canStartRegExp = true ;
74
- } else if ( canStartRegExp && ch == '/' ) {
75
- this . readRegexp ( ) ;
76
- canStartRegExp = false ;
77
- } else if ( this . isNumber ( ch ) ) {
78
- this . readNumber ( ) ;
79
- canStartRegExp = false ;
80
- } else if ( this . isIdent ( ch ) ) {
81
- this . readIdent ( ) ;
82
- canStartRegExp = false ;
83
- } else if ( this . isWhitespace ( ch ) ) {
84
- this . index ++ ;
72
+ var ch2 = ch + peek ( ) ,
73
+ fn = OPERATORS [ ch ] ,
74
+ fn2 = OPERATORS [ ch2 ] ;
75
+ if ( fn2 ) {
76
+ tokens . push ( { index :index , text :ch2 , fn :fn2 } ) ;
77
+ index += 2 ;
78
+ } else if ( fn ) {
79
+ tokens . push ( { index :index , text :ch , fn :fn } ) ;
80
+ index += 1 ;
85
81
} else {
86
- var ch2 = ch + this . peek ( ) ;
87
- var fn = OPERATORS [ ch ] ;
88
- var fn2 = OPERATORS [ ch2 ] ;
89
- if ( fn2 ) {
90
- tokens . push ( { index :this . index , text :ch2 , fn :fn2 } ) ;
91
- this . index += 2 ;
92
- } else if ( fn ) {
93
- tokens . push ( { index :this . index , text :ch , fn :fn } ) ;
94
- this . index += 1 ;
95
- } else {
96
- throw "Lexer Error: Unexpected next character [" +
97
- this . text . substring ( this . index ) +
98
- "] in expression '" + this . text +
99
- "' at column '" + ( this . index + 1 ) + "'." ;
100
- }
101
- canStartRegExp = true ;
82
+ throw "Lexer Error: Unexpected next character [" +
83
+ text . substring ( index ) +
84
+ "] in expression '" + text +
85
+ "' at column '" + ( index + 1 ) + "'." ;
102
86
}
87
+ canStartRegExp = true ;
103
88
}
104
- return tokens ;
105
- } ,
89
+ }
90
+ return tokens ;
106
91
107
- isNumber : function ( ch ) {
92
+ function peek ( ) {
93
+ return index + 1 < text . length ? text . charAt ( index + 1 ) : false ;
94
+ }
95
+ function isNumber ( ch ) {
108
96
return '0' <= ch && ch <= '9' ;
109
- } ,
110
-
111
- isWhitespace : function ( ch ) {
97
+ }
98
+ function isWhitespace ( ch ) {
112
99
return ch == ' ' || ch == '\r' || ch == '\t' ||
113
100
ch == '\n' || ch == '\v' ;
114
- } ,
115
-
116
- isIdent : function ( ch ) {
101
+ }
102
+ function isIdent ( ch ) {
117
103
return 'a' <= ch && ch <= 'z' ||
118
104
'A' <= ch && ch <= 'Z' ||
119
105
'_' == ch || ch == '$' ;
120
- } ,
121
-
122
- readNumber : function ( ) {
106
+ }
107
+ function readNumber ( ) {
123
108
var number = "" ;
124
- var start = this . index ;
125
- while ( this . index < this . text . length ) {
126
- var ch = this . text . charAt ( this . index ) ;
127
- if ( ch == '.' || this . isNumber ( ch ) ) {
109
+ var start = index ;
110
+ while ( index < text . length ) {
111
+ var ch = text . charAt ( index ) ;
112
+ if ( ch == '.' || isNumber ( ch ) ) {
128
113
number += ch ;
129
114
} else {
130
115
break ;
131
116
}
132
- this . index ++ ;
117
+ index ++ ;
133
118
}
134
119
number = 1 * number ;
135
- this . tokens . push ( { index :start , text :number ,
120
+ tokens . push ( { index :start , text :number ,
136
121
fn :function ( ) { return number ; } } ) ;
137
- } ,
138
-
139
- readIdent : function ( ) {
122
+ }
123
+ function readIdent ( ) {
140
124
var ident = "" ;
141
- var start = this . index ;
142
- while ( this . index < this . text . length ) {
143
- var ch = this . text . charAt ( this . index ) ;
144
- if ( ch == '.' || this . isIdent ( ch ) || this . isNumber ( ch ) ) {
125
+ var start = index ;
126
+ while ( index < text . length ) {
127
+ var ch = text . charAt ( index ) ;
128
+ if ( ch == '.' || isIdent ( ch ) || isNumber ( ch ) ) {
145
129
ident += ch ;
146
130
} else {
147
131
break ;
148
132
}
149
- this . index ++ ;
133
+ index ++ ;
150
134
}
151
135
var fn = OPERATORS [ ident ] ;
152
136
if ( ! fn ) {
153
137
fn = getterFn ( ident ) ;
154
138
fn . isAssignable = ident ;
155
139
}
156
- this . tokens . push ( { index :start , text :ident , fn :fn } ) ;
157
- } ,
158
-
159
- readString : function ( quote ) {
160
- var start = this . index ;
161
- var dateParseLength = this . dateParseLength ;
162
- this . index ++ ;
140
+ tokens . push ( { index :start , text :ident , fn :fn } ) ;
141
+ }
142
+ function readString ( quote ) {
143
+ var start = index ;
144
+ index ++ ;
163
145
var string = "" ;
164
146
var rawString = quote ;
165
147
var escape = false ;
166
- while ( this . index < this . text . length ) {
167
- var ch = this . text . charAt ( this . index ) ;
148
+ while ( index < text . length ) {
149
+ var ch = text . charAt ( index ) ;
168
150
rawString += ch ;
169
151
if ( escape ) {
170
152
if ( ch == 'u' ) {
171
- var hex = this . text . substring ( this . index + 1 , this . index + 5 ) ;
172
- this . index += 4 ;
153
+ var hex = text . substring ( index + 1 , index + 5 ) ;
154
+ index += 4 ;
173
155
string += String . fromCharCode ( parseInt ( hex , 16 ) ) ;
174
156
} else {
175
157
var rep = ESCAPE [ ch ] ;
@@ -183,8 +165,8 @@ Lexer.prototype = {
183
165
} else if ( ch == '\\' ) {
184
166
escape = true ;
185
167
} else if ( ch == quote ) {
186
- this . index ++ ;
187
- this . tokens . push ( { index :start , text :rawString , string :string ,
168
+ index ++ ;
169
+ tokens . push ( { index :start , text :rawString , string :string ,
188
170
fn :function ( ) {
189
171
return ( string . length == dateParseLength ) ?
190
172
angular [ 'String' ] [ 'toDate' ] ( string ) : string ;
@@ -193,53 +175,52 @@ Lexer.prototype = {
193
175
} else {
194
176
string += ch ;
195
177
}
196
- this . index ++ ;
178
+ index ++ ;
197
179
}
198
180
throw "Lexer Error: Unterminated quote [" +
199
- this . text . substring ( start ) + "] starting at column '" +
200
- ( start + 1 ) + "' in expression '" + this . text + "'." ;
201
- } ,
202
-
203
- readRegexp : function ( quote ) {
204
- var start = this . index ;
205
- this . index ++ ;
181
+ text . substring ( start ) + "] starting at column '" +
182
+ ( start + 1 ) + "' in expression '" + text + "'." ;
183
+ }
184
+ function readRegexp ( quote ) {
185
+ var start = index ;
186
+ index ++ ;
206
187
var regexp = "" ;
207
188
var escape = false ;
208
- while ( this . index < this . text . length ) {
209
- var ch = this . text . charAt ( this . index ) ;
189
+ while ( index < text . length ) {
190
+ var ch = text . charAt ( index ) ;
210
191
if ( escape ) {
211
192
regexp += ch ;
212
193
escape = false ;
213
194
} else if ( ch === '\\' ) {
214
195
regexp += ch ;
215
196
escape = true ;
216
197
} else if ( ch === '/' ) {
217
- this . index ++ ;
198
+ index ++ ;
218
199
var flags = "" ;
219
- if ( this . isIdent ( this . text . charAt ( this . index ) ) ) {
220
- this . readIdent ( ) ;
221
- flags = this . tokens . pop ( ) . text ;
200
+ if ( isIdent ( text . charAt ( index ) ) ) {
201
+ readIdent ( ) ;
202
+ flags = tokens . pop ( ) . text ;
222
203
}
223
204
var compiledRegexp = new RegExp ( regexp , flags ) ;
224
- this . tokens . push ( { index :start , text :regexp , flags :flags ,
205
+ tokens . push ( { index :start , text :regexp , flags :flags ,
225
206
fn :function ( ) { return compiledRegexp ; } } ) ;
226
207
return ;
227
208
} else {
228
209
regexp += ch ;
229
210
}
230
- this . index ++ ;
211
+ index ++ ;
231
212
}
232
213
throw "Lexer Error: Unterminated RegExp [" +
233
- this . text . substring ( start ) + "] starting at column '" +
234
- ( start + 1 ) + "' in expression '" + this . text + "'." ;
214
+ text . substring ( start ) + "] starting at column '" +
215
+ ( start + 1 ) + "' in expression '" + text + "'." ;
235
216
}
236
- } ;
217
+ }
237
218
238
219
/////////////////////////////////////////
239
220
240
221
function Parser ( text , parseStrings ) {
241
222
this . text = text ;
242
- this . tokens = new Lexer ( text , parseStrings ) . parse ( ) ;
223
+ this . tokens = lex ( text , parseStrings ) ;
243
224
this . index = 0 ;
244
225
}
245
226
0 commit comments