@@ -8,6 +8,7 @@ mod tests;
88
99use core:: str;
1010use std:: {
11+ cmp:: Ordering ,
1112 fmt:: { Debug , Display } ,
1213 slice:: SliceIndex ,
1314} ;
@@ -33,7 +34,7 @@ pub type Result<T, E = LexingError> = std::result::Result<T, E>;
3334#[ logos( subpattern ignore_with_nl = r"(?:(?&ignore)|\n)*" ) ]
3435#[ logos( error( LexingError , callback = |lex| LexingError :: unexpected( lex) ) ) ]
3536pub enum Token < ' a > {
36- #[ regex( r"[0-9]+(\.[0-9]+ )?([eE][+-]?[0-9]+)?" , parse_float) ]
37+ #[ regex( r"(-)? [0-9]+(\.[0-9]* )?([eE][+-]?[0-9]+)?" , parse_float) ]
3738 #[ regex( r"\.[0-9]+([eE][+-]?[0-9]+)?" , parse_float) ]
3839 Number ( f64 ) ,
3940 #[ token( "\" " , parse_string) ]
@@ -308,14 +309,15 @@ fn skip_line(lex: &mut Lexer<'_>) -> Skip {
308309}
309310
310311fn parse_string < ' a > ( lex : & mut logos:: Lexer < ' a , Token < ' a > > ) -> Result < Slice < ' a > > {
311- parse_content :: < false , false , '"' > ( lex)
312+ accept_operator ( lex) ;
313+ parse_content :: < false , '"' > ( lex)
312314}
313315
314316fn parse_regex_or_slash < ' a > ( lex : & mut logos:: Lexer < ' a , Token < ' a > > ) -> Result < Token < ' a > > {
315317 match lex. extras . ctx {
316318 Context :: AcceptExpression => {
317319 accept_operator ( lex) ;
318- parse_content :: < false , true , '/' > ( lex) . map ( Token :: Regex )
320+ parse_content :: < true , '/' > ( lex) . map ( Token :: Regex )
319321 }
320322 Context :: AcceptOperator => {
321323 accept_expression ( lex) ;
@@ -326,7 +328,7 @@ fn parse_regex_or_slash<'a>(lex: &mut logos::Lexer<'a, Token<'a>>) -> Result<Tok
326328
327329fn parse_directive < ' a > ( lex : & mut Lexer < ' a > ) -> Result < Slice < ' a > > {
328330 accept_expression ( lex) ;
329- parse_content :: < true , false , '"' > ( lex)
331+ parse_content :: < false , '"' > ( lex)
330332}
331333
332334fn parse_non_posix_directive < ' a > ( lex : & mut Lexer < ' a > ) -> Result < Slice < ' a > > {
@@ -347,7 +349,7 @@ fn parse_namespace_directive<'a>(lex: &mut Lexer<'a>) -> Result<&'a str> {
347349 }
348350}
349351
350- fn parse_content < ' a , const MINIMAL : bool , const REGEX : bool , const DELIMITER : char > (
352+ fn parse_content < ' a , const REGEX : bool , const DELIMITER : char > (
351353 lex : & mut Lexer < ' a > ,
352354) -> Result < Slice < ' a > > {
353355 let rest = lex. remainder ( ) ;
@@ -372,7 +374,7 @@ fn parse_content<'a, const MINIMAL: bool, const REGEX: bool, const DELIMITER: ch
372374 b'\\' => {
373375 out. to_mut ( lex. extras . arena ( ) )
374376 . extend_from_slice ( & rest[ start..i] ) ;
375- let consumed = parse_escape :: < MINIMAL , REGEX > (
377+ let consumed = parse_escape :: < REGEX > (
376378 & rest[ i..] ,
377379 out. to_mut ( lex. extras . arena ( ) ) ,
378380 lex. extras . posix_strict ,
@@ -389,7 +391,7 @@ fn parse_content<'a, const MINIMAL: bool, const REGEX: bool, const DELIMITER: ch
389391 }
390392}
391393
392- fn parse_escape < const MINIMAL : bool , const REGEX : bool > (
394+ fn parse_escape < const REGEX : bool > (
393395 slice : & [ u8 ] ,
394396 out : & mut Vec < u8 > ,
395397 posix_strict : bool ,
@@ -406,39 +408,30 @@ fn parse_escape<const MINIMAL: bool, const REGEX: bool>(
406408 }
407409
408410 // On minimal, only drop backslash for '"' and '\n'
409- let escaped = if MINIMAL && !matches ! ( to_escape, '"' | '\n' ) {
410- out. push ( b'\\' ) ;
411- to_escape
412- } else if MINIMAL {
413- to_escape
414- } else {
415- match to_escape {
416- c @ ( '\\' | '"' ) if !REGEX => c,
417- c @ ( '[' | ']' | '{' | '}' | '(' | ')' | '*' | '+' | '^' | '$' | '.' | '?' )
418- if REGEX =>
419- {
420- out. push ( b'\\' ) ;
421- c
422- }
423- 'a' => 7 as char ,
424- 'b' => 8 as char ,
425- 'f' => 12 as char ,
426- 'n' => '\n' ,
427- 'r' => '\r' ,
428- 't' => '\t' ,
429- 'v' => 11 as char ,
430- n if is_oct ( n) => {
431- count += is_slice_oct ( 2 ) as usize + ( is_slice_oct ( 2 ) && is_slice_oct ( 3 ) ) as usize ;
432- slice[ 1 ..]
433- . iter ( )
434- . take ( count - 1 )
435- . fold ( 0 , |acc, digit| acc * 8 + digit - b'0' ) as char
436- }
437- 'x' if !posix_strict => todo ! ( ) ,
438- 'u' => todo ! ( ) ,
439- // Unspecified by POSIX; we ditto GNU.
440- c => c, // TODO: Output warning
411+ let escaped = match to_escape {
412+ c @ ( '\\' | '"' ) if !REGEX => c,
413+ c @ ( '[' | ']' | '{' | '}' | '(' | ')' | '*' | '+' | '^' | '$' | '.' | '?' ) if REGEX => {
414+ out. push ( b'\\' ) ;
415+ c
416+ }
417+ 'a' => 7 as char ,
418+ 'b' => 8 as char ,
419+ 'f' => 12 as char ,
420+ 'n' => '\n' ,
421+ 'r' => '\r' ,
422+ 't' => '\t' ,
423+ 'v' => 11 as char ,
424+ n if is_oct ( n) => {
425+ count += is_slice_oct ( 2 ) as usize + ( is_slice_oct ( 2 ) && is_slice_oct ( 3 ) ) as usize ;
426+ slice[ 1 ..]
427+ . iter ( )
428+ . take ( count - 1 )
429+ . fold ( 0 , |acc, digit| acc * 8 + digit - b'0' ) as char
441430 }
431+ 'x' if !posix_strict => todo ! ( ) ,
432+ 'u' => todo ! ( ) ,
433+ // Unspecified by POSIX; we ditto GNU.
434+ c => c, // TODO: Output warning
442435 } ;
443436 out. push ( escaped as u8 ) ;
444437 Ok ( count)
@@ -511,7 +504,7 @@ fn accept_operator(lex: &mut Lexer<'_>) {
511504 lex. extras . ctx = Context :: AcceptOperator ;
512505}
513506
514- #[ derive( PartialEq , Eq , PartialOrd , Ord , Clone ) ]
507+ #[ derive( Clone ) ]
515508pub enum Slice < ' a > {
516509 Borrowed ( & ' a [ u8 ] ) ,
517510 Owned ( Vec < ' a , u8 > ) ,
@@ -556,12 +549,38 @@ impl<'a> From<&'a [u8]> for Slice<'a> {
556549 }
557550}
558551
552+ impl < ' a , const N : usize > From < & ' a [ u8 ; N ] > for Slice < ' a > {
553+ fn from ( value : & ' a [ u8 ; N ] ) -> Self {
554+ Self :: Borrowed ( value)
555+ }
556+ }
557+
559558impl < ' a > From < Vec < ' a , u8 > > for Slice < ' a > {
560559 fn from ( value : Vec < ' a , u8 > ) -> Self {
561560 Self :: Owned ( value)
562561 }
563562}
564563
564+ impl PartialEq for Slice < ' _ > {
565+ fn eq ( & self , other : & Self ) -> bool {
566+ self . as_ref ( ) == other. as_ref ( )
567+ }
568+ }
569+
570+ impl Eq for Slice < ' _ > { }
571+
572+ impl PartialOrd for Slice < ' _ > {
573+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
574+ Some ( self . cmp ( other) )
575+ }
576+ }
577+
578+ impl Ord for Slice < ' _ > {
579+ fn cmp ( & self , other : & Self ) -> Ordering {
580+ self . as_ref ( ) . cmp ( other. as_ref ( ) )
581+ }
582+ }
583+
565584impl Extra {
566585 fn arena < ' a > ( & self ) -> & ' a Bump {
567586 // SAFETY: lives for as long as self because it's the same lifetime as
0 commit comments