@@ -47,14 +47,14 @@ pub enum Token<'a> {
4747 BeginFilePattern ,
4848 #[ token( "ENDFILE" , |lex| parse_non_posix_keyword( lex, Token :: EndFilePattern ) ) ]
4949 EndFilePattern ,
50- #[ token( "@load \" " , parse_directive ) ]
51- LoadDirective ( Slice < ' a > ) ,
52- #[ token( "@include \" " , parse_directive ) ]
53- IncludeDirective ( Slice < ' a > ) ,
54- #[ token( "@nsinclude \" " , parse_non_posix_directive ) ]
55- NsIncludeDirective ( Slice < ' a > ) ,
56- #[ regex( "@namespace \" (?&identifier) \" " , parse_namespace_directive ) ]
57- NamespaceDirective ( & ' a str ) ,
50+ #[ token( "@load" ) ]
51+ LoadDirective ,
52+ #[ token( "@include" ) ]
53+ IncludeDirective ,
54+ #[ token( "@nsinclude" , parse_non_posix_operator ) ]
55+ NsIncludeDirective ,
56+ #[ regex( "@namespace" , parse_non_posix_operator ) ]
57+ NamespaceDirective ,
5858 #[ token( "@concurrent" , parse_non_gnu_operator) ]
5959 ConcurrentDirective ,
6060 #[ token( "if" , accept_expression) ]
@@ -130,9 +130,12 @@ pub enum Token<'a> {
130130 RlengthVariable ,
131131 #[ token( "ENVIRON" , accept_expression) ]
132132 EnvironVariable ,
133- #[ regex( "(?&identifier)" , Identifier :: without_namespace) ]
134- #[ regex( r"(?&identifier)::(?&identifier)" , Identifier :: with_namespace) ]
133+ #[ regex( "(?&identifier)" , Identifier :: without_namespace:: < 0 > ) ]
134+ #[ regex( r"(?&identifier)::(?&identifier)" , Identifier :: with_namespace:: < 0 > ) ]
135135 Identifier ( Identifier < ' a > ) ,
136+ #[ regex( "@(?&identifier)" , parse_indirect_call:: <false >) ]
137+ #[ regex( r"@(?&identifier)::(?&identifier)" , parse_indirect_call:: <true >) ]
138+ IndirectCall ( Identifier < ' a > ) ,
136139 #[ token( "+" , accept_expression) ]
137140 Plus ,
138141 #[ token( "-" , accept_expression) ]
@@ -333,29 +336,6 @@ fn parse_regex_or_op<'a>(lex: &mut logos::Lexer<'a, Token<'a>>) -> Result<Token<
333336 }
334337}
335338
336- fn parse_directive < ' a > ( lex : & mut Lexer < ' a > ) -> Result < Slice < ' a > > {
337- accept_expression ( lex) ;
338- parse_content :: < false , '"' > ( lex)
339- }
340-
341- fn parse_non_posix_directive < ' a > ( lex : & mut Lexer < ' a > ) -> Result < Slice < ' a > > {
342- if lex. extras . posix_strict {
343- Err ( LexingError :: non_posix ( lex) )
344- } else {
345- parse_directive ( lex)
346- }
347- }
348-
349- fn parse_namespace_directive < ' a > ( lex : & mut Lexer < ' a > ) -> Result < & ' a str > {
350- if lex. extras . posix_strict {
351- Err ( LexingError :: non_posix ( lex) )
352- } else {
353- accept_expression ( lex) ;
354- let offset = "@namespace \" " . len ( ) ;
355- Ok ( parse_ident ( lex, offset..lex. slice ( ) . len ( ) - 1 ) )
356- }
357- }
358-
359339fn parse_content < ' a , const REGEX : bool , const DELIMITER : char > (
360340 lex : & mut Lexer < ' a > ,
361341) -> Result < Slice < ' a > > {
@@ -456,7 +436,7 @@ fn parse_float(lex: &mut Lexer<'_>) -> f64 {
456436
457437fn parse_non_posix_keyword < ' a > ( lex : & mut Lexer < ' a > , other : Token < ' a > ) -> Token < ' a > {
458438 if lex. extras . posix_strict {
459- Token :: Identifier ( Identifier :: without_namespace ( lex) )
439+ Token :: Identifier ( Identifier :: without_namespace :: < 0 > ( lex) )
460440 } else {
461441 accept_expression ( lex) ;
462442 other
@@ -481,22 +461,32 @@ fn parse_non_gnu_operator(lex: &mut Lexer<'_>) -> Result<()> {
481461 }
482462}
483463
464+ fn parse_indirect_call < ' a , const QUALIFIED : bool > ( lex : & mut Lexer < ' a > ) -> Result < Identifier < ' a > > {
465+ if lex. extras . posix_strict {
466+ Err ( LexingError :: non_posix ( lex) )
467+ } else if QUALIFIED {
468+ Identifier :: with_namespace :: < 1 > ( lex)
469+ } else {
470+ Ok ( Identifier :: without_namespace :: < 1 > ( lex) )
471+ }
472+ }
473+
484474impl < ' a > Identifier < ' a > {
485- fn without_namespace ( lex : & mut Lexer < ' a > ) -> Self {
475+ fn without_namespace < const SKIP : usize > ( lex : & mut Lexer < ' a > ) -> Self {
486476 Self {
487477 namespace : None ,
488- literal : parse_ident ( lex, ..) ,
478+ literal : parse_ident ( lex, SKIP ..) ,
489479 }
490480 }
491481
492- fn with_namespace ( lex : & mut Lexer < ' a > ) -> Result < Self > {
482+ fn with_namespace < const SKIP : usize > ( lex : & mut Lexer < ' a > ) -> Result < Self > {
493483 if lex. extras . posix_strict {
494484 Err ( LexingError :: non_posix ( lex) )
495485 } else {
496486 // SAFETY: The regex matching ensures it is present and well-formed.
497487 let separator = unsafe { memchr ( b':' , lex. slice ( ) ) . unwrap_unchecked ( ) } ;
498488 Ok ( Self {
499- namespace : Some ( parse_ident ( lex, ..separator) ) ,
489+ namespace : Some ( parse_ident ( lex, SKIP ..separator) ) ,
500490 literal : parse_ident ( lex, separator + 2 ..) ,
501491 } )
502492 }
0 commit comments