View Javadoc
1   // $ANTLR 2.7.7 (20060906): "distinguishedName.g" -> "AntlrDnParser.java"$
2   
3   /*
4    *  Licensed to the Apache Software Foundation (ASF) under one
5    *  or more contributor license agreements.  See the NOTICE file
6    *  distributed with this work for additional information
7    *  regarding copyright ownership.  The ASF licenses this file
8    *  to you under the Apache License, Version 2.0 (the
9    *  "License"); you may not use this file except in compliance
10   *  with the License.  You may obtain a copy of the License at
11   *  
12   *    http://www.apache.org/licenses/LICENSE-2.0
13   *  
14   *  Unless required by applicable law or agreed to in writing,
15   *  software distributed under the License is distributed on an
16   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   *  KIND, either express or implied.  See the License for the
18   *  specific language governing permissions and limitations
19   *  under the License. 
20   *  
21   */
22  package org.apache.directory.api.ldap.model.name;
23  
24  import java.io.StringReader;
25  import java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  
30  import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
31  import javax.naming.NameParser;
32  import org.apache.directory.api.ldap.model.entry.StringValue;
33  import org.apache.directory.api.ldap.model.entry.BinaryValue;
34  import org.apache.directory.api.ldap.model.schema.parsers.ParserMonitor;
35  import org.apache.directory.api.util.Strings;
36  
37  
38  import antlr.TokenBuffer;
39  import antlr.TokenStreamException;
40  import antlr.TokenStreamIOException;
41  import antlr.ANTLRException;
42  import antlr.LLkParser;
43  import antlr.Token;
44  import antlr.TokenStream;
45  import antlr.RecognitionException;
46  import antlr.NoViableAltException;
47  import antlr.MismatchedTokenException;
48  import antlr.SemanticException;
49  import antlr.ParserSharedInputState;
50  import antlr.collections.impl.BitSet;
51  
52  /**
53   * An antlr generated Dn parser.
54   *
55   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
56   */
57  public class AntlrDnParser extends antlr.LLkParser       implements AntlrDnTokenTypes
58   {
59  
60      private ParserMonitor monitor = null;
61      public void setParserMonitor( ParserMonitor monitor )
62      {
63          this.monitor = monitor;
64      }
65      private void matchedProduction( String msg )
66      {
67          if ( null != monitor )
68          {
69              monitor.matchedProduction( msg );
70          }
71      }
72      static class UpAndNormValue
73      {
74          Object value = "";
75          String rawValue = "";
76      }
77  
78  protected AntlrDnParser(TokenBuffer tokenBuf, int k) {
79    super(tokenBuf,k);
80    tokenNames = _tokenNames;
81  }
82  
83  public AntlrDnParser(TokenBuffer tokenBuf) {
84    this(tokenBuf,3);
85  }
86  
87  protected AntlrDnParser(TokenStream lexer, int k) {
88    super(lexer,k);
89    tokenNames = _tokenNames;
90  }
91  
92  public AntlrDnParser(TokenStream lexer) {
93    this(lexer,3);
94  }
95  
96  public AntlrDnParser(ParserSharedInputState state) {
97    super(state,3);
98    tokenNames = _tokenNames;
99  }
100 
101 /**
102      * Parses an Dn string.
103      *
104      * RFC 4514, Section 3
105      * distinguishedName = [ relativeDistinguishedName
106      *     *( COMMA relativeDistinguishedName ) ]
107      *
108      * RFC 2253, Section 3
109      * distinguishedName = [name] 
110      * name       = name-component *("," name-component)
111      *
112      * RFC 1779, Section 2.3
113      * <name> ::= <name-component> ( <spaced-separator> )
114      *        | <name-component> <spaced-separator> <name>
115      * <spaced-separator> ::= <optional-space>
116      *             <separator>
117      *             <optional-space>
118      * <separator> ::=  "," | ";"
119      * <optional-space> ::= ( <CR> ) *( " " )
120      *
121      */
122 	public final void distinguishedName(
123 		Dn dn
124 	) throws RecognitionException, TokenStreamException {
125 		
126 		
127 		matchedProduction( "distinguishedName()" );
128 		Rdn rdn = null;
129 		
130 		
131 		{
132 		switch ( LA(1)) {
133 		case SPACE:
134 		case NUMERICOID:
135 		case ALPHA:
136 		{
137 			rdn=relativeDistinguishedName(new Rdn());
138 			
139 			try
140 			{ 
141 			dn.add( rdn ); 
142 			}
143 			catch ( LdapInvalidDnException lide )
144 			{
145 			// Do nothing, can't get an exception here
146 			} 
147 			
148 			rdn=null; 
149 			
150 			{
151 			_loop53:
152 			do {
153 				if ((LA(1)==COMMA||LA(1)==SEMI)) {
154 					{
155 					switch ( LA(1)) {
156 					case COMMA:
157 					{
158 						match(COMMA);
159 						break;
160 					}
161 					case SEMI:
162 					{
163 						match(SEMI);
164 						break;
165 					}
166 					default:
167 					{
168 						throw new NoViableAltException(LT(1), getFilename());
169 					}
170 					}
171 					}
172 					rdn=relativeDistinguishedName(new Rdn());
173 					
174 					try
175 					{ 
176 					dn.add( rdn ); 
177 					}
178 					catch ( LdapInvalidDnException lide )
179 					{
180 					// Do nothing, can't get an exception here
181 					} 
182 					
183 					rdn=null;
184 					
185 				}
186 				else {
187 					break _loop53;
188 				}
189 				
190 			} while (true);
191 			}
192 			match(Token.EOF_TYPE);
193 			break;
194 		}
195 		case EOF:
196 		{
197 			break;
198 		}
199 		default:
200 		{
201 			throw new NoViableAltException(LT(1), getFilename());
202 		}
203 		}
204 		}
205 	}
206 	
207 /**
208      * Parses an Rdn string.
209      *
210      * RFC 4514, Section 3
211      * relativeDistinguishedName = attributeTypeAndValue
212      *     *( PLUS attributeTypeAndValue )
213      *
214      * RFC 2253, Section 3
215      * name-component = attributeTypeAndValue *("+" attributeTypeAndValue)
216      *
217      * RFC 1779, Section 2.3
218      * <name-component> ::= <attribute>
219      *     | <attribute> <optional-space> "+"
220      *       <optional-space> <name-component>
221      *
222      */
223 	public final Rdn  relativeDistinguishedName(
224 		Rdn initialRdn
225 	) throws RecognitionException, TokenStreamException {
226 		Rdn rdn;
227 		
228 		
229 		matchedProduction( "relativeDistinguishedName()" );
230 		rdn = initialRdn;
231 		String tmp;
232 		String upName = "";
233 		
234 		
235 		{
236 		tmp=attributeTypeAndValue(rdn);
237 		
238 		upName += tmp;
239 		
240 		{
241 		_loop62:
242 		do {
243 			if ((LA(1)==PLUS)) {
244 				match(PLUS);
245 				upName += "+";
246 				tmp=attributeTypeAndValue(rdn);
247 				
248 				upName += tmp;
249 				
250 			}
251 			else {
252 				break _loop62;
253 			}
254 			
255 		} while (true);
256 		}
257 		}
258 		
259 		rdn.normalize();
260 		rdn.setUpName( upName );
261 		
262 		return rdn;
263 	}
264 	
265 /**
266      * Parses an Dn string.
267      *
268      * RFC 4514, Section 3
269      * distinguishedName = [ relativeDistinguishedName
270      *     *( COMMA relativeDistinguishedName ) ]
271      *
272      * RFC 2253, Section 3
273      * distinguishedName = [name] 
274      * name       = name-component *("," name-component)
275      *
276      * RFC 1779, Section 2.3
277      * <name> ::= <name-component> ( <spaced-separator> )
278      *        | <name-component> <spaced-separator> <name>
279      * <spaced-separator> ::= <optional-space>
280      *             <separator>
281      *             <optional-space>
282      * <separator> ::=  "," | ";"
283      * <optional-space> ::= ( <CR> ) *( " " )
284      *
285      */
286 	public final void relativeDistinguishedNames(
287 		List<Rdn> rdns
288 	) throws RecognitionException, TokenStreamException {
289 		
290 		
291 		matchedProduction( "relativeDistinguishedNames()" );
292 		Rdn rdn = null;
293 		
294 		
295 		{
296 		switch ( LA(1)) {
297 		case SPACE:
298 		case NUMERICOID:
299 		case ALPHA:
300 		{
301 			rdn=relativeDistinguishedName(new Rdn());
302 			
303 			rdns.add( rdn );
304 			
305 			{
306 			_loop58:
307 			do {
308 				if ((LA(1)==COMMA||LA(1)==SEMI)) {
309 					{
310 					switch ( LA(1)) {
311 					case COMMA:
312 					{
313 						match(COMMA);
314 						break;
315 					}
316 					case SEMI:
317 					{
318 						match(SEMI);
319 						break;
320 					}
321 					default:
322 					{
323 						throw new NoViableAltException(LT(1), getFilename());
324 					}
325 					}
326 					}
327 					rdn=relativeDistinguishedName(new Rdn());
328 					
329 					rdns.add( rdn ); 
330 					
331 				}
332 				else {
333 					break _loop58;
334 				}
335 				
336 			} while (true);
337 			}
338 			match(Token.EOF_TYPE);
339 			break;
340 		}
341 		case EOF:
342 		{
343 			break;
344 		}
345 		default:
346 		{
347 			throw new NoViableAltException(LT(1), getFilename());
348 		}
349 		}
350 		}
351 	}
352 	
353 /**
354      * RFC 4514, Section 3
355      * attributeTypeAndValue = attributeType EQUALS attributeValue
356      *
357      * RFC 2253, Section 3
358      * attributeTypeAndValue = attributeType "=" attributeValue
359      *
360      */
361 	public final String  attributeTypeAndValue(
362 		Rdn rdn
363 	) throws RecognitionException, TokenStreamException {
364 		String upName = "";
365 		
366 		
367 		matchedProduction( "attributeTypeAndValue()" );
368 		String type = null;
369 		UpAndNormValue value = new UpAndNormValue();
370 		String upValue = null;
371 		
372 		
373 		{
374 		{
375 		_loop66:
376 		do {
377 			if ((LA(1)==SPACE)) {
378 				match(SPACE);
379 				upName += " ";
380 			}
381 			else {
382 				break _loop66;
383 			}
384 			
385 		} while (true);
386 		}
387 		type=attributeType();
388 		upName += type;
389 		{
390 		_loop68:
391 		do {
392 			if ((LA(1)==SPACE)) {
393 				match(SPACE);
394 				upName += " ";
395 			}
396 			else {
397 				break _loop68;
398 			}
399 			
400 		} while (true);
401 		}
402 		match(EQUALS);
403 		upName += "=";
404 		{
405 		_loop70:
406 		do {
407 			if ((LA(1)==SPACE)) {
408 				match(SPACE);
409 				
410 				upName += " "; 
411 				
412 				if ( upValue == null )
413 				{
414 				upValue = " ";
415 				}
416 				else
417 				{
418 				upValue += " "; 
419 				} 
420 				
421 			}
422 			else {
423 				break _loop70;
424 			}
425 			
426 		} while (true);
427 		}
428 		attributeValue(value);
429 		
430 		try
431 		{
432 		upName += value.rawValue;
433 		Ava ava = null;
434 		
435 		if ( value.value instanceof String )
436 		{
437 		if ( upValue != null )
438 		{
439 		value.rawValue = upValue + value.rawValue;
440 		}
441 		
442 		Object unescapedValue = Rdn.unescapeValue( Strings.trim( (String)value.rawValue ) );
443 		
444 		if ( unescapedValue instanceof String )
445 		{
446 		ava = new Ava(
447 		type,
448 		type,
449 		new StringValue( (String)unescapedValue ),
450 		new StringValue( (String)value.value ), 
451 		upName
452 		);
453 		}
454 		else
455 		{
456 		ava = new Ava(
457 		type,
458 		type,
459 		new BinaryValue( (byte[])unescapedValue ),
460 		new StringValue( (String)value.value ), 
461 		upName
462 		);
463 		}
464 		}
465 		else
466 		{
467 		ava = new Ava(
468 		type,
469 		type,
470 		new BinaryValue( (byte[])value.value ), 
471 		new BinaryValue( (byte[])value.value ),
472 		upName
473 		);
474 		}
475 		
476 		rdn.addAVA( null, ava );
477 		}
478 		catch ( LdapInvalidDnException e )
479 		{
480 		throw new SemanticException( e.getMessage() );
481 		} 
482 		
483 		}
484 		return upName;
485 	}
486 	
487 /**
488      * RFC 4514 Section 3
489      *
490      * attributeType = descr / numericoid
491      *
492      */
493 	public final String  attributeType() throws RecognitionException, TokenStreamException {
494 		String attributeType;
495 		
496 		
497 		matchedProduction( "attributeType()" );
498 		
499 		
500 		{
501 		switch ( LA(1)) {
502 		case ALPHA:
503 		{
504 			attributeType=descr();
505 			break;
506 		}
507 		case NUMERICOID:
508 		{
509 			attributeType=numericoid();
510 			break;
511 		}
512 		default:
513 		{
514 			throw new NoViableAltException(LT(1), getFilename());
515 		}
516 		}
517 		}
518 		return attributeType;
519 	}
520 	
521 /**
522      * RFC 4514, Section 3
523      * attributeValue = string / hexstring
524      *
525      * RFC 2253, Section 3
526      * attributeValue = string
527      * string     = *( stringchar / pair )
528      *              / "#" hexstring
529      *              / QUOTATION *( quotechar / pair ) QUOTATION ; only from v2
530      * 
531      */
532 	public final void attributeValue(
533 		UpAndNormValue value
534 	) throws RecognitionException, TokenStreamException {
535 		
536 		
537 		matchedProduction( "attributeValue()" );
538 		
539 		
540 		{
541 		switch ( LA(1)) {
542 		case DQUOTE:
543 		{
544 			{
545 			quotestring(value);
546 			{
547 			_loop81:
548 			do {
549 				if ((LA(1)==SPACE)) {
550 					match(SPACE);
551 					value.rawValue += " ";
552 				}
553 				else {
554 					break _loop81;
555 				}
556 				
557 			} while (true);
558 			}
559 			}
560 			break;
561 		}
562 		case EQUALS:
563 		case HYPHEN:
564 		case UNDERSCORE:
565 		case NUMERICOID:
566 		case DIGIT:
567 		case ALPHA:
568 		case HEXPAIR:
569 		case ESC:
570 		case ESCESC:
571 		case ESCSHARP:
572 		case UTFMB:
573 		case LUTF1_REST:
574 		{
575 			string(value);
576 			break;
577 		}
578 		case HEXVALUE:
579 		{
580 			{
581 			hexstring(value);
582 			{
583 			_loop84:
584 			do {
585 				if ((LA(1)==SPACE)) {
586 					match(SPACE);
587 					value.rawValue += " ";
588 				}
589 				else {
590 					break _loop84;
591 				}
592 				
593 			} while (true);
594 			}
595 			}
596 			break;
597 		}
598 		case EOF:
599 		case COMMA:
600 		case PLUS:
601 		case SEMI:
602 		{
603 			break;
604 		}
605 		default:
606 		{
607 			throw new NoViableAltException(LT(1), getFilename());
608 		}
609 		}
610 		}
611 	}
612 	
613 /**
614      * RFC 4512 Section 1.4
615      *
616      * descr = keystring
617      * keystring = leadkeychar *keychar
618      * leadkeychar = ALPHA
619      * keychar = ALPHA / DIGIT / HYPHEN
620      *
621      * We additionally add UNDERSCORE because some servers allow them.
622      *
623      */
624 	public final String  descr() throws RecognitionException, TokenStreamException {
625 		String descr;
626 		
627 		Token  leadkeychar = null;
628 		Token  alpha = null;
629 		Token  digit = null;
630 		Token  hyphen = null;
631 		Token  underscore = null;
632 		
633 		matchedProduction( "descr()" );
634 		
635 		
636 		leadkeychar = LT(1);
637 		match(ALPHA);
638 		descr = leadkeychar.getText();
639 		{
640 		_loop75:
641 		do {
642 			switch ( LA(1)) {
643 			case ALPHA:
644 			{
645 				alpha = LT(1);
646 				match(ALPHA);
647 				descr += alpha.getText();
648 				break;
649 			}
650 			case DIGIT:
651 			{
652 				digit = LT(1);
653 				match(DIGIT);
654 				descr += digit.getText();
655 				break;
656 			}
657 			case HYPHEN:
658 			{
659 				hyphen = LT(1);
660 				match(HYPHEN);
661 				descr += hyphen.getText();
662 				break;
663 			}
664 			case UNDERSCORE:
665 			{
666 				underscore = LT(1);
667 				match(UNDERSCORE);
668 				descr += underscore.getText();
669 				break;
670 			}
671 			default:
672 			{
673 				break _loop75;
674 			}
675 			}
676 		} while (true);
677 		}
678 		return descr;
679 	}
680 	
681 /**
682      * RFC 4512 Section 1.4
683      *
684      * numericoid = number 1*( DOT number )
685      * number  = DIGIT / ( LDIGIT 1*DIGIT )
686      * DIGIT   = %x30 / LDIGIT       ; "0"-"9"
687      * LDIGIT  = %x31-39             ; "1"-"9"
688      *
689      */
690 	public final String  numericoid() throws RecognitionException, TokenStreamException {
691 		String numericoid = "";
692 		
693 		Token  noid = null;
694 		
695 		matchedProduction( "numericoid()" );
696 		
697 		
698 		noid = LT(1);
699 		match(NUMERICOID);
700 		numericoid += noid.getText();
701 		return numericoid;
702 	}
703 	
704 /**
705      * RFC 2253, Section 3
706      *              / QUOTATION *( quotechar / pair ) QUOTATION ; only from v2
707      * quotechar     = <any character except "\" or QUOTATION >
708      *
709      */
710 	public final void quotestring(
711 		UpAndNormValue value
712 	) throws RecognitionException, TokenStreamException {
713 		
714 		Token  dq1 = null;
715 		Token  s = null;
716 		Token  dq2 = null;
717 		
718 		matchedProduction( "quotestring()" );
719 		org.apache.directory.api.util.ByteBuffer bb = new org.apache.directory.api.util.ByteBuffer();
720 		byte[] bytes;
721 		
722 		
723 		{
724 		dq1 = LT(1);
725 		match(DQUOTE);
726 		value.rawValue += dq1.getText();
727 		{
728 		_loop90:
729 		do {
730 			switch ( LA(1)) {
731 			case COMMA:
732 			case EQUALS:
733 			case PLUS:
734 			case HYPHEN:
735 			case UNDERSCORE:
736 			case SEMI:
737 			case LANGLE:
738 			case RANGLE:
739 			case SPACE:
740 			case NUMERICOID_OR_ALPHA_OR_DIGIT:
741 			case NUMERICOID:
742 			case DOT:
743 			case NUMBER:
744 			case LDIGIT:
745 			case DIGIT:
746 			case ALPHA:
747 			case HEXPAIR_OR_ESCESC_ESCSHARP_OR_ESC:
748 			case HEX:
749 			case HEXVALUE_OR_SHARP:
750 			case HEXVALUE:
751 			case SHARP:
752 			case UTFMB:
753 			case LUTF1_REST:
754 			{
755 				{
756 				{
757 				s = LT(1);
758 				match(_tokenSet_0);
759 				}
760 				
761 				value.rawValue += s.getText();
762 				bb.append( Strings.getBytesUtf8( s.getText() ) );
763 				
764 				}
765 				break;
766 			}
767 			case HEXPAIR:
768 			case ESC:
769 			case ESCESC:
770 			case ESCSHARP:
771 			{
772 				bytes=pair(value);
773 				bb.append( bytes );
774 				break;
775 			}
776 			default:
777 			{
778 				break _loop90;
779 			}
780 			}
781 		} while (true);
782 		}
783 		dq2 = LT(1);
784 		match(DQUOTE);
785 		value.rawValue += dq2.getText();
786 		}
787 		
788 		String string = Strings.utf8ToString( bb.copyOfUsedBytes() );
789 		value.value = string;
790 		
791 	}
792 	
793 /**
794      * RFC 4514 Section 3
795      *
796      * ; The following characters are to be escaped when they appear
797      * ; in the value to be encoded: ESC, one of <escaped>, leading
798      * ; SHARP or SPACE, trailing SPACE, and NULL.
799      * string =   [ ( leadchar / pair ) [ *( stringchar / pair )
800      *    ( trailchar / pair ) ] ]
801      *
802      */
803 	public final void string(
804 		UpAndNormValue value
805 	) throws RecognitionException, TokenStreamException {
806 		
807 		
808 		matchedProduction( "string()" );
809 		org.apache.directory.api.util.ByteBuffer bb = new org.apache.directory.api.util.ByteBuffer();
810 		String tmp;
811 		byte[] bytes;
812 		
813 		
814 		{
815 		{
816 		switch ( LA(1)) {
817 		case EQUALS:
818 		case HYPHEN:
819 		case UNDERSCORE:
820 		case NUMERICOID:
821 		case DIGIT:
822 		case ALPHA:
823 		case LUTF1_REST:
824 		{
825 			tmp=lutf1();
826 			
827 			value.rawValue += tmp;
828 			bb.append( Strings.getBytesUtf8( tmp ) );
829 			
830 			break;
831 		}
832 		case UTFMB:
833 		{
834 			tmp=utfmb();
835 			
836 			value.rawValue += tmp;
837 			bb.append( Strings.getBytesUtf8( tmp ) );
838 			
839 			break;
840 		}
841 		case HEXPAIR:
842 		case ESC:
843 		case ESCESC:
844 		case ESCSHARP:
845 		{
846 			bytes=pair(value);
847 			bb.append( bytes );
848 			break;
849 		}
850 		default:
851 		{
852 			throw new NoViableAltException(LT(1), getFilename());
853 		}
854 		}
855 		}
856 		{
857 		_loop96:
858 		do {
859 			switch ( LA(1)) {
860 			case EQUALS:
861 			case HYPHEN:
862 			case UNDERSCORE:
863 			case SPACE:
864 			case NUMERICOID:
865 			case DIGIT:
866 			case ALPHA:
867 			case HEXVALUE:
868 			case SHARP:
869 			case LUTF1_REST:
870 			{
871 				tmp=sutf1();
872 				
873 				value.rawValue += tmp;
874 				bb.append( Strings.getBytesUtf8( tmp ) );
875 				
876 				break;
877 			}
878 			case UTFMB:
879 			{
880 				tmp=utfmb();
881 				
882 				value.rawValue += tmp;
883 				bb.append( Strings.getBytesUtf8( tmp ) );
884 				
885 				break;
886 			}
887 			case HEXPAIR:
888 			case ESC:
889 			case ESCESC:
890 			case ESCSHARP:
891 			{
892 				bytes=pair(value);
893 				bb.append( bytes );
894 				break;
895 			}
896 			default:
897 			{
898 				break _loop96;
899 			}
900 			}
901 		} while (true);
902 		}
903 		}
904 		
905 		String string = Strings.utf8ToString( bb.copyOfUsedBytes() );
906 		
907 		// trim trailing space characters manually
908 		// don't know how to tell antlr that the last char mustn't be a space.
909 		int rawIndex = value.rawValue.length();
910 		while ( string.length() > 0 && rawIndex > 1 
911 		&& value.rawValue.charAt( rawIndex - 1 ) == ' ' 
912 		&& value.rawValue.charAt( rawIndex - 2 ) != '\\' )
913 		{
914 		string = string.substring( 0, string.length() - 1 );
915 		rawIndex--;
916 		}
917 		
918 		value.value = string;
919 		
920 	}
921 	
922 /**
923      * RFC 4514 Section 3
924      *
925      * hexstring = SHARP 1*hexpair
926      *
927      * If in <hexstring> form, a BER representation can be obtained from
928      * converting each <hexpair> of the <hexstring> to the octet indicated
929      * by the <hexpair>.
930      *
931      */
932 	public final void hexstring(
933 		UpAndNormValue value
934 	) throws RecognitionException, TokenStreamException {
935 		
936 		Token  hexValue = null;
937 		
938 		matchedProduction( "hexstring()" );
939 		
940 		
941 		hexValue = LT(1);
942 		match(HEXVALUE);
943 		
944 		// convert to byte[]
945 		value.rawValue = "#" + hexValue.getText();
946 		value.value = Strings.toByteArray( hexValue.getText() ); 
947 		
948 	}
949 	
950 /**
951      * RFC 4514, Section 3
952      * pair = ESC ( ESC / special / hexpair )
953      * special = escaped / SPACE / SHARP / EQUALS
954      * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
955      * hexpair = HEX HEX
956      *
957      * If in <string> form, a LDAP string representation asserted value can
958      * be obtained by replacing (left to right, non-recursively) each <pair>
959      * appearing in the <string> as follows:
960      *   replace <ESC><ESC> with <ESC>;
961      *   replace <ESC><special> with <special>;
962      *   replace <ESC><hexpair> with the octet indicated by the <hexpair>.
963      * 
964      * RFC 2253, Section 3
965      * pair       = "\" ( special / "\" / QUOTATION / hexpair )
966      * special    = "," / "=" / "+" / "<" /  ">" / "#" / ";"
967      * 
968      * RFC 1779, Section 2.3
969      * <pair> ::= "\" ( <special> | "\" | '"')
970      * <special> ::= "," | "=" | <CR> | "+" | "<" |  ">"
971      *           | "#" | ";"
972      * 
973      */
974 	public final byte[]  pair(
975 		UpAndNormValue value
976 	) throws RecognitionException, TokenStreamException {
977 		byte[] pair;
978 		
979 		Token  hexpair = null;
980 		
981 		matchedProduction( "pair()" );
982 		String tmp;
983 		
984 		
985 		switch ( LA(1)) {
986 		case ESCESC:
987 		{
988 			{
989 			match(ESCESC);
990 			
991 			value.rawValue += "\\\\";
992 			pair = Strings.getBytesUtf8( "\\" );
993 			
994 			}
995 			break;
996 		}
997 		case ESCSHARP:
998 		{
999 			{
1000 			match(ESCSHARP);
1001 			
1002 			value.rawValue += "\\#";
1003 			pair = Strings.getBytesUtf8( "#" );
1004 			
1005 			}
1006 			break;
1007 		}
1008 		case ESC:
1009 		{
1010 			{
1011 			match(ESC);
1012 			tmp=special();
1013 			
1014 			value.rawValue += "\\" + tmp;
1015 			pair = Strings.getBytesUtf8( tmp );
1016 			
1017 			}
1018 			break;
1019 		}
1020 		case HEXPAIR:
1021 		{
1022 			{
1023 			hexpair = LT(1);
1024 			match(HEXPAIR);
1025 			
1026 			value.rawValue += "\\" + hexpair.getText();
1027 			pair = Strings.toByteArray( hexpair.getText() ); 
1028 			
1029 			}
1030 			break;
1031 		}
1032 		default:
1033 		{
1034 			throw new NoViableAltException(LT(1), getFilename());
1035 		}
1036 		}
1037 		return pair;
1038 	}
1039 	
1040 /**
1041  * RFC 4514, Section 3:
1042  * LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A /
1043  *    %x3D / %x3F-5B / %x5D-7F
1044  *
1045  * The rule LUTF1_REST doesn't contain the following charcters,
1046  * so we must check them additionally
1047  *   EQUALS (0x3D)
1048  *   HYPHEN (0x2D)
1049  *   UNDERSCORE (0x5F)
1050  *   DIGIT (0x30-0x39)
1051  *   ALPHA (0x41-0x5A and 0x61-0x7A)
1052  */
1053 	public final String  lutf1() throws RecognitionException, TokenStreamException {
1054 		String lutf1="";
1055 		
1056 		Token  rest = null;
1057 		Token  equals = null;
1058 		Token  hyphen = null;
1059 		Token  underscore = null;
1060 		Token  digit = null;
1061 		Token  alpha = null;
1062 		Token  numericoid = null;
1063 		
1064 		matchedProduction( "lutf1()" );
1065 		
1066 		
1067 		switch ( LA(1)) {
1068 		case LUTF1_REST:
1069 		{
1070 			rest = LT(1);
1071 			match(LUTF1_REST);
1072 			lutf1 = rest.getText();
1073 			break;
1074 		}
1075 		case EQUALS:
1076 		{
1077 			equals = LT(1);
1078 			match(EQUALS);
1079 			lutf1 = equals.getText();
1080 			break;
1081 		}
1082 		case HYPHEN:
1083 		{
1084 			hyphen = LT(1);
1085 			match(HYPHEN);
1086 			lutf1 = hyphen.getText();
1087 			break;
1088 		}
1089 		case UNDERSCORE:
1090 		{
1091 			underscore = LT(1);
1092 			match(UNDERSCORE);
1093 			lutf1 = underscore.getText();
1094 			break;
1095 		}
1096 		case DIGIT:
1097 		{
1098 			digit = LT(1);
1099 			match(DIGIT);
1100 			lutf1 = digit.getText();
1101 			break;
1102 		}
1103 		case ALPHA:
1104 		{
1105 			alpha = LT(1);
1106 			match(ALPHA);
1107 			lutf1 = alpha.getText();
1108 			break;
1109 		}
1110 		case NUMERICOID:
1111 		{
1112 			numericoid = LT(1);
1113 			match(NUMERICOID);
1114 			lutf1 = numericoid.getText();
1115 			break;
1116 		}
1117 		default:
1118 		{
1119 			throw new NoViableAltException(LT(1), getFilename());
1120 		}
1121 		}
1122 		return lutf1;
1123 	}
1124 	
1125 	public final String  utfmb() throws RecognitionException, TokenStreamException {
1126 		String utfmb;
1127 		
1128 		Token  s = null;
1129 		
1130 		matchedProduction( "utfmb()" );
1131 		
1132 		
1133 		s = LT(1);
1134 		match(UTFMB);
1135 		utfmb = s.getText();
1136 		return utfmb;
1137 	}
1138 	
1139 /**
1140  * RFC 4514, Section 3:
1141  * SUTF1 = %x01-21 / %x23-2A / %x2D-3A /
1142  *    %x3D / %x3F-5B / %x5D-7F
1143  *
1144  * The rule LUTF1_REST doesn't contain the following charcters,
1145  * so we must check them additionally
1146  *   EQUALS (0x3D)
1147  *   HYPHEN (0x2D)
1148  *   UNDERSCORE (0x5F)
1149  *   DIGIT (0x30-0x39)
1150  *   ALPHA (0x41-0x5A and 0x61-0x7A)
1151  *   SHARP
1152  *   SPACE
1153  */
1154 	public final String  sutf1() throws RecognitionException, TokenStreamException {
1155 		String sutf1="";
1156 		
1157 		Token  rest = null;
1158 		Token  equals = null;
1159 		Token  hyphen = null;
1160 		Token  underscore = null;
1161 		Token  digit = null;
1162 		Token  alpha = null;
1163 		Token  sharp = null;
1164 		Token  space = null;
1165 		Token  hex = null;
1166 		Token  numericoid = null;
1167 		
1168 		matchedProduction( "sutf1()" );
1169 		
1170 		
1171 		switch ( LA(1)) {
1172 		case LUTF1_REST:
1173 		{
1174 			rest = LT(1);
1175 			match(LUTF1_REST);
1176 			sutf1 = rest.getText();
1177 			break;
1178 		}
1179 		case EQUALS:
1180 		{
1181 			equals = LT(1);
1182 			match(EQUALS);
1183 			sutf1 = equals.getText();
1184 			break;
1185 		}
1186 		case HYPHEN:
1187 		{
1188 			hyphen = LT(1);
1189 			match(HYPHEN);
1190 			sutf1 = hyphen.getText();
1191 			break;
1192 		}
1193 		case UNDERSCORE:
1194 		{
1195 			underscore = LT(1);
1196 			match(UNDERSCORE);
1197 			sutf1 = underscore.getText();
1198 			break;
1199 		}
1200 		case DIGIT:
1201 		{
1202 			digit = LT(1);
1203 			match(DIGIT);
1204 			sutf1 = digit.getText();
1205 			break;
1206 		}
1207 		case ALPHA:
1208 		{
1209 			alpha = LT(1);
1210 			match(ALPHA);
1211 			sutf1 = alpha.getText();
1212 			break;
1213 		}
1214 		case SHARP:
1215 		{
1216 			sharp = LT(1);
1217 			match(SHARP);
1218 			sutf1 = sharp.getText();
1219 			break;
1220 		}
1221 		case SPACE:
1222 		{
1223 			space = LT(1);
1224 			match(SPACE);
1225 			sutf1 = space.getText();
1226 			break;
1227 		}
1228 		case HEXVALUE:
1229 		{
1230 			hex = LT(1);
1231 			match(HEXVALUE);
1232 			sutf1 = "#" + hex.getText();
1233 			break;
1234 		}
1235 		case NUMERICOID:
1236 		{
1237 			numericoid = LT(1);
1238 			match(NUMERICOID);
1239 			sutf1 = numericoid.getText();
1240 			break;
1241 		}
1242 		default:
1243 		{
1244 			throw new NoViableAltException(LT(1), getFilename());
1245 		}
1246 		}
1247 		return sutf1;
1248 	}
1249 	
1250 /**
1251      * RFC 4514 Section 3
1252      * 
1253      * special = escaped / SPACE / SHARP / EQUALS
1254      * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
1255      *
1256      */
1257 	public final String  special() throws RecognitionException, TokenStreamException {
1258 		String special;
1259 		
1260 		Token  dquote = null;
1261 		Token  plus = null;
1262 		Token  comma = null;
1263 		Token  semi = null;
1264 		Token  langle = null;
1265 		Token  rangle = null;
1266 		Token  space = null;
1267 		Token  sharp = null;
1268 		Token  equals = null;
1269 		
1270 		matchedProduction( "special()" );
1271 		
1272 		
1273 		{
1274 		switch ( LA(1)) {
1275 		case DQUOTE:
1276 		{
1277 			dquote = LT(1);
1278 			match(DQUOTE);
1279 			special = dquote.getText();
1280 			break;
1281 		}
1282 		case PLUS:
1283 		{
1284 			plus = LT(1);
1285 			match(PLUS);
1286 			special = plus.getText();
1287 			break;
1288 		}
1289 		case COMMA:
1290 		{
1291 			comma = LT(1);
1292 			match(COMMA);
1293 			special = comma.getText();
1294 			break;
1295 		}
1296 		case SEMI:
1297 		{
1298 			semi = LT(1);
1299 			match(SEMI);
1300 			special = semi.getText();
1301 			break;
1302 		}
1303 		case LANGLE:
1304 		{
1305 			langle = LT(1);
1306 			match(LANGLE);
1307 			special = langle.getText();
1308 			break;
1309 		}
1310 		case RANGLE:
1311 		{
1312 			rangle = LT(1);
1313 			match(RANGLE);
1314 			special = rangle.getText();
1315 			break;
1316 		}
1317 		case SPACE:
1318 		{
1319 			space = LT(1);
1320 			match(SPACE);
1321 			special = space.getText();
1322 			break;
1323 		}
1324 		case SHARP:
1325 		{
1326 			sharp = LT(1);
1327 			match(SHARP);
1328 			special = sharp.getText();
1329 			break;
1330 		}
1331 		case EQUALS:
1332 		{
1333 			equals = LT(1);
1334 			match(EQUALS);
1335 			special = equals.getText();
1336 			break;
1337 		}
1338 		default:
1339 		{
1340 			throw new NoViableAltException(LT(1), getFilename());
1341 		}
1342 		}
1343 		}
1344 		return special;
1345 	}
1346 	
1347 	
1348 	public static final String[] _tokenNames = {
1349 		"<0>",
1350 		"EOF",
1351 		"<2>",
1352 		"NULL_TREE_LOOKAHEAD",
1353 		"COMMA",
1354 		"EQUALS",
1355 		"PLUS",
1356 		"HYPHEN",
1357 		"UNDERSCORE",
1358 		"DQUOTE",
1359 		"SEMI",
1360 		"LANGLE",
1361 		"RANGLE",
1362 		"SPACE",
1363 		"NUMERICOID_OR_ALPHA_OR_DIGIT",
1364 		"NUMERICOID",
1365 		"DOT",
1366 		"NUMBER",
1367 		"LDIGIT",
1368 		"DIGIT",
1369 		"ALPHA",
1370 		"HEXPAIR_OR_ESCESC_ESCSHARP_OR_ESC",
1371 		"HEXPAIR",
1372 		"ESC",
1373 		"ESCESC",
1374 		"ESCSHARP",
1375 		"HEX",
1376 		"HEXVALUE_OR_SHARP",
1377 		"HEXVALUE",
1378 		"SHARP",
1379 		"UTFMB",
1380 		"LUTF1_REST"
1381 	};
1382 	
1383 	private static final long[] mk_tokenSet_0() {
1384 		long[] data = { 4232052208L, 0L, 0L, 0L};
1385 		return data;
1386 	}
1387 	public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
1388 	
1389 	}