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