docs: public final EObject ruleTerminalToken() throws RecognitionException {
          EObject current = null;
  
          Token lv_cardinality_1_1=null;
          Token lv_cardinality_1_2=null;
          Token lv_cardinality_1_3=null;
          EObject this_TerminalTokenElement_0 = null;
  
  
  
          	enterRule();
  
          try {
              // InternalXtext.g:3128:2: ( (this_TerminalTokenElement_0= ruleTerminalTokenElement ( ( (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' ) ) )? ) )
              // InternalXtext.g:3129:2: (this_TerminalTokenElement_0= ruleTerminalTokenElement ( ( (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' ) ) )? )
              {
              // InternalXtext.g:3129:2: (this_TerminalTokenElement_0= ruleTerminalTokenElement ( ( (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' ) ) )? )
              // InternalXtext.g:3130:3: this_TerminalTokenElement_0= ruleTerminalTokenElement ( ( (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' ) ) )?
              {
  
              			newCompositeNode(grammarAccess.getTerminalTokenAccess().getTerminalTokenElementParserRuleCall_0());
              		
              pushFollow(FollowSets000.FOLLOW_31);
              this_TerminalTokenElement_0=ruleTerminalTokenElement();
  
              state._fsp--;
  
  
              			current = this_TerminalTokenElement_0;
              			afterParserOrEnumRuleCall();
              		
              // InternalXtext.g:3138:3: ( ( (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' ) ) )?
              int alt70=2;
              int LA70_0 = input.LA(1);
  
              if ( (LA70_0==23||(LA70_0>=32 && LA70_0<=33)) ) {
                  alt70=1;
              }
              switch (alt70) {
                  case 1 :
                      // InternalXtext.g:3139:4: ( (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' ) )
                      {
                      // InternalXtext.g:3139:4: ( (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' ) )
                      // InternalXtext.g:3140:5: (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' )
                      {
                      // InternalXtext.g:3140:5: (lv_cardinality_1_1= '?' | lv_cardinality_1_2= '*' | lv_cardinality_1_3= '+' )
                      int alt69=3;
                      switch ( input.LA(1) ) {
                      case 32:
                          {
                          alt69=1;
                          }
                          break;
                      case 23:
                          {
                          alt69=2;
                          }
                          break;
                      case 33:
                          {
                          alt69=3;
                          }
                          break;
                      default:
                          NoViableAltException nvae =
                              new NoViableAltException("", 69, 0, input);
  
                          throw nvae;
                      }
  
                      switch (alt69) {
                          case 1 :
                              // InternalXtext.g:3141:6: lv_cardinality_1_1= '?'
                              {
                              lv_cardinality_1_1=(Token)match(input,32,FollowSets000.FOLLOW_2); 
  
                              						newLeafNode(lv_cardinality_1_1, grammarAccess.getTerminalTokenAccess().getCardinalityQuestionMarkKeyword_1_0_0());
                              					
  
                              						if (current==null) {
                              							current = createModelElement(grammarAccess.getTerminalTokenRule());
                              						}
                              						setWithLastConsumed(current, "cardinality", lv_cardinality_1_1, null);
                              					
  
                              }
                              break;
                          case 2 :
                              // InternalXtext.g:3152:6: lv_cardinality_1_2= '*'
                              {
                              lv_cardinality_1_2=(Token)match(input,23,FollowSets000.FOLLOW_2); 
  
                              						newLeafNode(lv_cardinality_1_2, grammarAccess.getTerminalTokenAccess().getCardinalityAsteriskKeyword_1_0_1());
                              					
  
                              						if (current==null) {
                              							current = createModelElement(grammarAccess.getTerminalTokenRule());
                              						}
                              						setWithLastConsumed(current, "cardinality", lv_cardinality_1_2, null);
                              					
  
                              }
                              break;
                          case 3 :
                              // InternalXtext.g:3163:6: lv_cardinality_1_3= '+'
                              {
                              lv_cardinality_1_3=(Token)match(input,33,FollowSets000.FOLLOW_2); 
  
                              						newLeafNode(lv_cardinality_1_3, grammarAccess.getTerminalTokenAccess().getCardinalityPlusSignKeyword_1_0_2());
                              					
  
                              						if (current==null) {
                              							current = createModelElement(grammarAccess.getTerminalTokenRule());
                              						}
                              						setWithLastConsumed(current, "cardinality", lv_cardinality_1_3, null);
                              					
  
                              }
                              break;
  
                      }
  
  
                      }
  
  
                      }
                      break;
  
              }
  
  
              }
  
  
              }
  
  
              	leaveRule();
  
          }
  
              catch (RecognitionException re) {
                  recover(input,re);
                  appendSkippedTokens();
              }
          finally {
          }
          return current;
      }