@@ -413,51 +413,67 @@ export function createParser(
413413 return attr ;
414414 }
415415
416- function parseNumber ( signed : boolean ) {
416+ function parseNumber ( ) {
417417 let result = '' ;
418- if ( signed && is ( '-' ) ) {
419- result = readAndNext ( ) ;
420- }
421418 while ( digitsChars [ chr ] ) {
422419 result += readAndNext ( ) ;
423420 }
424- assert ( result !== '' && result !== '-' , 'Formula parse error.' ) ;
421+ assert ( result !== '' , 'Formula parse error.' ) ;
425422 return parseInt ( result ) ;
426423 }
427424
428425 const isNumberStart = ( ) => is ( '-' ) || is ( '+' ) || digitsChars [ chr ] ;
429426
430427 function parseFormula ( ) : [ number , number ] {
428+ if ( is ( 'e' ) || is ( 'o' ) ) {
429+ const ident = parseIdentifier ( ) ;
430+ if ( ident === 'even' ) {
431+ skipWhitespace ( ) ;
432+ return [ 2 , 0 ] ;
433+ }
434+ if ( ident === 'odd' ) {
435+ skipWhitespace ( ) ;
436+ return [ 2 , 1 ] ;
437+ }
438+ }
439+
431440 let firstNumber : null | number = null ;
441+ let firstNumberMultiplier = 1 ;
442+ if ( is ( '-' ) ) {
443+ next ( ) ;
444+ firstNumberMultiplier = - 1 ;
445+ }
432446 if ( isNumberStart ( ) ) {
433447 if ( is ( '+' ) ) {
434448 next ( ) ;
435- assert ( ! is ( '-' ) , 'Formula parse error.' ) ;
436449 }
437- firstNumber = parseNumber ( true ) ;
450+ firstNumber = parseNumber ( ) ;
438451 if ( ! is ( '\\' ) && ! is ( 'n' ) ) {
439- return [ 0 , firstNumber ] ;
452+ return [ 0 , firstNumber * firstNumberMultiplier ] ;
440453 }
441454 }
442455 if ( firstNumber === null ) {
443456 firstNumber = 1 ;
444457 }
445- const ident = parseIdentifier ( ) ;
446- if ( ident === 'even' ) {
447- skipWhitespace ( ) ;
448- return [ 2 , 0 ] ;
449- }
450- if ( ident === 'odd' ) {
451- skipWhitespace ( ) ;
452- return [ 2 , 1 ] ;
458+ firstNumber *= firstNumberMultiplier ;
459+ let identifier ;
460+ if ( is ( '\\' ) ) {
461+ next ( ) ;
462+ if ( isHex ( chr ) ) {
463+ identifier = parseHex ( ) ;
464+ } else {
465+ identifier = readAndNext ( ) ;
466+ }
467+ } else {
468+ identifier = readAndNext ( ) ;
453469 }
454- assert ( ident === 'n' , 'Formula parse error' ) ;
470+ assert ( identifier === 'n' , 'Formula parse error: expected "n". ' ) ;
455471 skipWhitespace ( ) ;
456472 if ( is ( '+' ) || is ( '-' ) ) {
457473 const sign = is ( '+' ) ? 1 : - 1 ;
458474 next ( ) ;
459475 skipWhitespace ( ) ;
460- return [ firstNumber , sign * parseNumber ( false ) ] ;
476+ return [ firstNumber , sign * parseNumber ( ) ] ;
461477 } else {
462478 return [ firstNumber , 0 ] ;
463479 }
0 commit comments