docs: public final AntlrDatatypeRuleToken ruleQualifiedName() throws RecognitionException {
          AntlrDatatypeRuleToken current = new AntlrDatatypeRuleToken();
  
          Token kw=null;
          AntlrDatatypeRuleToken this_ValidID_0 = null;
  
          AntlrDatatypeRuleToken this_ValidID_2 = null;
  
  
  
          	enterRule();
  
          try {
              // InternalSARL.g:15753:2: ( (this_ValidID_0= ruleValidID ( ( ( '.' )=>kw= '.' ) this_ValidID_2= ruleValidID )* ) )
              // InternalSARL.g:15754:2: (this_ValidID_0= ruleValidID ( ( ( '.' )=>kw= '.' ) this_ValidID_2= ruleValidID )* )
              {
              // InternalSARL.g:15754:2: (this_ValidID_0= ruleValidID ( ( ( '.' )=>kw= '.' ) this_ValidID_2= ruleValidID )* )
              // InternalSARL.g:15755:3: this_ValidID_0= ruleValidID ( ( ( '.' )=>kw= '.' ) this_ValidID_2= ruleValidID )*
              {
              if ( state.backtracking==0 ) {
  
                			newCompositeNode(grammarAccess.getQualifiedNameAccess().getValidIDParserRuleCall_0());
                		
              }
              pushFollow(FOLLOW_93);
              this_ValidID_0=ruleValidID();
  
              state._fsp--;
              if (state.failed) return current;
              if ( state.backtracking==0 ) {
  
                			current.merge(this_ValidID_0);
                		
              }
              if ( state.backtracking==0 ) {
  
                			afterParserOrEnumRuleCall();
                		
              }
              // InternalSARL.g:15765:3: ( ( ( '.' )=>kw= '.' ) this_ValidID_2= ruleValidID )*
              loop360:
              do {
                  int alt360=2;
                  alt360 = dfa360.predict(input);
                  switch (alt360) {
              	case 1 :
              	    // InternalSARL.g:15766:4: ( ( '.' )=>kw= '.' ) this_ValidID_2= ruleValidID
              	    {
              	    // InternalSARL.g:15766:4: ( ( '.' )=>kw= '.' )
              	    // InternalSARL.g:15767:5: ( '.' )=>kw= '.'
              	    {
              	    kw=(Token)match(input,77,FOLLOW_3); if (state.failed) return current;
              	    if ( state.backtracking==0 ) {
  
              	      					current.merge(kw);
              	      					newLeafNode(kw, grammarAccess.getQualifiedNameAccess().getFullStopKeyword_1_0());
              	      				
              	    }
  
              	    }
  
              	    if ( state.backtracking==0 ) {
  
              	      				newCompositeNode(grammarAccess.getQualifiedNameAccess().getValidIDParserRuleCall_1_1());
              	      			
              	    }
              	    pushFollow(FOLLOW_93);
              	    this_ValidID_2=ruleValidID();
  
              	    state._fsp--;
              	    if (state.failed) return current;
              	    if ( state.backtracking==0 ) {
  
              	      				current.merge(this_ValidID_2);
              	      			
              	    }
              	    if ( state.backtracking==0 ) {
  
              	      				afterParserOrEnumRuleCall();
              	      			
              	    }
  
              	    }
              	    break;
  
              	default :
              	    break loop360;
                  }
              } while (true);
  
  
              }
  
  
              }
  
              if ( state.backtracking==0 ) {
  
                	leaveRule();
  
              }
          }
  
              catch (RecognitionException re) {
                  recover(input,re);
                  appendSkippedTokens();
              }
          finally {
          }
          return current;
      }