@@ -74,8 +74,7 @@ function isSpecialCharacter(code: u32): bool {
7474}
7575
7676class Range {
77- from : i32 = - 1 ;
78- to : i32 = - 1 ;
77+ constructor ( public from : i32 , public to : i32 ) { }
7978}
8079
8180export class Parser {
@@ -157,64 +156,54 @@ export class Parser {
157156 return new CharacterNode ( this . eatToken ( ) ) ;
158157 }
159158
160- private maybeParseRepetitionRange ( ) : Range | null {
161- // snapshot
162- const iteratorCopy = this . iterator . copy ( ) ;
163- this . eatToken ( Char . LeftCurlyBrace ) ;
164-
165- let range = new Range ( ) ;
166-
167- let firstDigit = true ;
159+ private maybeParseDigit ( ) : i32 {
168160 let digitStr = "" ;
169161 while ( this . iterator . more ( ) ) {
170162 const token = this . iterator . current ;
171- if ( token == Char . RightParenthesis ) break ;
172- if ( firstDigit ) {
173- if ( isDigit ( token ) ) {
174- // if it is a digit, keep eating
175- digitStr += this . iterator . currentAsString ( ) ;
176- } else {
177- range . from = digitStr . length ? < i32 > parseInt ( digitStr ) : - 1 ;
178- range . to = range . from ;
179- if ( token == Char . Comma ) {
180- // if we meet a comma, start parsing the next digit
181- firstDigit = false ;
182- digitStr = "" ;
183- range . to = - 1 ;
184- } else if ( token == Char . RightCurlyBrace ) {
185- this . eatToken ( Char . RightCurlyBrace ) ;
186- // close brace, this is a single value range
187- return range ;
188- } else {
189- // anything else, we got a problem
190- break ;
191- }
192- }
163+ if ( isDigit ( token ) ) {
164+ digitStr += this . iterator . currentAsString ( ) ;
193165 } else {
194- if ( isDigit ( token ) ) {
195- // if it is a digit, keep eating
196- digitStr += this . iterator . currentAsString ( ) ;
197- } else {
198- range . to = digitStr . length ? < i32 > parseInt ( digitStr ) : - 1 ;
199- if ( token == Char . RightCurlyBrace ) {
200- this . eatToken ( Char . RightCurlyBrace ) ;
201- // close brace, end of range
202- return range ;
203- } else {
204- // anything else, we got a problem
205- break ;
206- }
207- }
166+ return digitStr == "" ? - 1 : < i32 > parseInt ( digitStr ) ;
208167 }
209168 this . eatToken ( ) ;
210169 }
170+ return digitStr == "" ? - 1 : < i32 > parseInt ( digitStr ) ;
171+ }
211172
212- // repetition not found - reset state
213- this . iterator = iteratorCopy ;
173+ private maybeParseRepetitionRange ( ) : Range | null {
174+ // snapshot
175+ const iteratorCopy = this . iterator . copy ( ) ;
176+ this . eatToken ( Char . LeftCurlyBrace ) ;
177+
178+ const from = this . maybeParseDigit ( ) ;
179+ if ( from == - 1 ) {
180+ return null ;
181+ }
182+ if ( this . iterator . current == Char . RightCurlyBrace ) {
183+ this . eatToken ( ) ;
184+ return new Range ( from , from ) ;
185+ } else if ( this . iterator . current == Char . Comma ) {
186+ this . eatToken ( ) ;
187+ const to = this . maybeParseDigit ( ) ;
188+ // @ts -ignore
189+ if ( this . iterator . current == Char . RightCurlyBrace ) {
190+ this . eatToken ( ) ;
191+ return new Range ( from , to ) ;
192+ }
193+ }
214194
195+ this . iterator = iteratorCopy ;
215196 return null ;
216197 }
217198
199+ private isGreedy ( ) : bool {
200+ if ( this . iterator . current == Char . Question ) {
201+ this . eatToken ( ) ;
202+ return false ;
203+ }
204+ return true ;
205+ }
206+
218207 // parses a sequence of chars
219208 private parseSequence ( ) : Node {
220209 let nodes = new Array < Node > ( ) ;
@@ -236,13 +225,13 @@ export class Parser {
236225 const range = this . maybeParseRepetitionRange ( ) ;
237226 if ( range != null ) {
238227 const expression = nodes . pop ( ) ;
239- let greedy = true ;
240- if ( this . iterator . current == Char . Question ) {
241- greedy = false ;
242- this . eatToken ( ) ;
243- }
244228 nodes . push (
245- new RangeRepetitionNode ( expression , range . from , range . to , greedy )
229+ new RangeRepetitionNode (
230+ expression ,
231+ range . from ,
232+ range . to ,
233+ this . isGreedy ( )
234+ )
246235 ) ;
247236 } else {
248237 // this is not the start of a repetition, it's just a char!
@@ -251,12 +240,7 @@ export class Parser {
251240 } else if ( isQuantifier ( token ) ) {
252241 const expression = nodes . pop ( ) ;
253242 const quantifier = this . eatToken ( ) ;
254- let greedy = true ;
255- if ( this . iterator . current == Char . Question ) {
256- greedy = false ;
257- this . eatToken ( ) ;
258- }
259- nodes . push ( new RepetitionNode ( expression , quantifier , greedy ) ) ;
243+ nodes . push ( new RepetitionNode ( expression , quantifier , this . isGreedy ( ) ) ) ;
260244 // @ts -ignore
261245 } else if ( token == Char . LeftSquareBracket ) {
262246 nodes . push ( this . parseCharacterSet ( ) ) ;
0 commit comments