88mod ast;
99mod diagnostics;
1010mod idempotency;
11+ mod keywords;
1112mod lex;
1213mod pratt;
1314mod sexpr;
@@ -134,7 +135,14 @@ impl<'a> Parser<'a> {
134135 }
135136 Token :: NamespaceDirective => {
136137 let namespace = lex. expect_string ( ) ?;
137- self . namespace = lex. lex_ident ( namespace. as_ref ( ) , self . arena ) ?;
138+ let namespace = lex. lex_ident ( namespace. as_ref ( ) , self . arena ) ?;
139+ if keywords:: is_reserved_keyword ( namespace) {
140+ return Err ( ParsingError :: ReservedNamespace (
141+ lex. span ( ) ,
142+ namespace. to_string ( ) ,
143+ ) ) ;
144+ }
145+ self . namespace = namespace;
138146 lex. expect_with ( Token :: is_stmnt_end, "expected statement end." . into ( ) ) ?;
139147 }
140148 Token :: ConcurrentDirective => {
@@ -544,8 +552,13 @@ impl<'a> Parser<'a> {
544552
545553 fn parse_delete ( & mut self , lex : & mut Lexer < ' a > ) -> Result < SimpleStatement < ' a > > {
546554 let next = lex. expect_next ( ) ?;
547- let Ok ( var) = self . get_place ( lex, next) else {
548- return Err ( ParsingError :: OperatorExpectsVariable ( lex. span ( ) ) ) ;
555+ let var = match self . get_place ( lex, next) {
556+ Ok ( var) => var,
557+ Err (
558+ err @ ( ParsingError :: ReservedNamespace ( ..)
559+ | ParsingError :: ReservedQualifiedLiteral ( ..) ) ,
560+ ) => return Err ( err) ,
561+ Err ( _) => return Err ( ParsingError :: OperatorExpectsVariable ( lex. span ( ) ) ) ,
549562 } ;
550563 let index = if lex. consume ( & Token :: OpenBracket ) {
551564 let mut pratt = Pratt :: new ( self , false ) ;
@@ -561,7 +574,9 @@ impl<'a> Parser<'a> {
561574
562575 #[ tracing:: instrument]
563576 fn parse_function ( & mut self , lex : & mut Lexer < ' a > ) -> Result < ( ) > {
564- let name = lex. expect_identifier ( ) ?. qualify ( self . namespace ) ;
577+ let name = lex
578+ . expect_identifier ( ) ?
579+ . try_qualify ( self . namespace , & lex. span ( ) ) ?;
565580 let args = self . parse_signature ( lex, & name) ?;
566581 lex. consume ( & Token :: Newline ) ;
567582 let body = self . parse_body ( lex) ?;
@@ -586,7 +601,9 @@ impl<'a> Parser<'a> {
586601 }
587602
588603 loop {
589- let name = lex. expect_identifier ( ) ?. qualify ( self . namespace ) ;
604+ let name = lex
605+ . expect_identifier ( ) ?
606+ . try_qualify ( self . namespace , & lex. span ( ) ) ?;
590607 // Linear search is fine for the numbers we are working with.
591608 if let Some ( arg) = args. iter ( ) . find ( |& a| a == & name) {
592609 return Err ( ParsingError :: DuplicatedArgument (
@@ -658,6 +675,10 @@ impl<'a> Parser<'a> {
658675 Token :: TypedRegex ( _) => Err ( ParsingError :: UnexpectedTypedRegex ( lex. span ( ) ) ) ,
659676 token => match self . get_place ( lex, token) {
660677 Ok ( var) => Ok ( Atom :: Variable ( var) ) ,
678+ Err (
679+ err @ ( ParsingError :: ReservedNamespace ( ..)
680+ | ParsingError :: ReservedQualifiedLiteral ( ..) ) ,
681+ ) => Err ( err) ,
661682 Err ( _) => Err ( ParsingError :: UnexpectedToken (
662683 lex. span ( ) ,
663684 "is not valid data." . into ( ) ,
@@ -667,10 +688,10 @@ impl<'a> Parser<'a> {
667688 }
668689
669690 #[ tracing:: instrument]
670- fn get_place ( & self , lex : & mut Lexer < ' a > , token : Token < ' a > ) -> Result < Variable < ' a > , Token < ' a > > {
691+ fn get_place ( & self , lex : & mut Lexer < ' a > , token : Token < ' a > ) -> Result < Variable < ' a > > {
671692 match token {
672693 Token :: Identifier ( a) if !( lex. peek_is ( & Token :: OpenParent ) && lex. is_yuxtaposed ( ) ) => {
673- Ok ( a. qualify ( self . namespace ) . into ( ) )
694+ Ok ( a. try_qualify ( self . namespace , & lex . span ( ) ) ? . into ( ) )
674695 }
675696 Token :: NrVariable => Ok ( Variable :: Nr ) ,
676697 Token :: NfVariable => Ok ( Variable :: Nf ) ,
@@ -687,7 +708,10 @@ impl<'a> Parser<'a> {
687708 Token :: RstartVariable => Ok ( Variable :: Rstart ) ,
688709 Token :: RlengthVariable => Ok ( Variable :: Rlength ) ,
689710 Token :: EnvironVariable => Ok ( Variable :: Environ ) ,
690- tok => Err ( tok) ,
711+ tok => Err ( ParsingError :: UnexpectedToken (
712+ lex. span ( ) ,
713+ format ! ( "{tok:?}" ) ,
714+ ) ) ,
691715 }
692716 }
693717}
@@ -717,22 +741,35 @@ impl Preprocessor {
717741}
718742
719743trait IdentifierExt < ' a > {
720- fn qualify ( self , namespace : & ' a str ) -> Identifier < ' a >
744+ fn try_qualify ( self , namespace : & ' a str , span : & Span ) -> Result < Identifier < ' a > >
721745 where
722746 Self : ' a ;
723747}
724748
725749impl < ' a > IdentifierExt < ' a > for lexer:: Identifier < ' _ > {
726- fn qualify ( self , namespace : & ' a str ) -> Identifier < ' a >
750+ fn try_qualify ( self , namespace : & ' a str , span : & Span ) -> Result < Identifier < ' a > >
727751 where
728752 Self : ' a ,
729753 {
730754 let literal = self . literal ;
731- if let Some ( namespace) = self . namespace {
732- Identifier { namespace, literal }
755+ let namespace = if let Some ( ns) = self . namespace {
756+ if keywords:: is_reserved_keyword ( ns) {
757+ return Err ( ParsingError :: ReservedNamespace (
758+ span. clone ( ) ,
759+ ns. to_string ( ) ,
760+ ) ) ;
761+ }
762+ if keywords:: is_reserved_keyword ( literal) {
763+ return Err ( ParsingError :: ReservedQualifiedLiteral (
764+ span. clone ( ) ,
765+ literal. to_string ( ) ,
766+ ) ) ;
767+ }
768+ ns
733769 } else {
734- Identifier { namespace, literal }
735- }
770+ namespace
771+ } ;
772+ Ok ( Identifier { namespace, literal } )
736773 }
737774}
738775
0 commit comments