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                            _loop1921:
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 _loop1921;
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                    _loop1930:
218                    do {
219                            if ((LA(1)==SPACE)) {
220                                    match(SPACE);
221                                    upName += " ";
222                            }
223                            else {
224                                    break _loop1930;
225                            }
226                            
227                    } while (true);
228                    }
229                    tmp=attributeTypeAndValue(rdn);
230                    
231                    upName += tmp;
232                    
233                    {
234                    _loop1934:
235                    do {
236                            if ((LA(1)==PLUS)) {
237                                    match(PLUS);
238                                    upName += "+";
239                                    {
240                                    _loop1933:
241                                    do {
242                                            if ((LA(1)==SPACE)) {
243                                                    match(SPACE);
244                                                    upName += " ";
245                                            }
246                                            else {
247                                                    break _loop1933;
248                                            }
249                                            
250                                    } while (true);
251                                    }
252                                    tmp=attributeTypeAndValue(rdn);
253                                    
254                                    upName += tmp;
255                                    
256                            }
257                            else {
258                                    break _loop1934;
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                            _loop1926:
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 _loop1926;
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                    _loop1938:
379                    do {
380                            if ((LA(1)==SPACE)) {
381                                    match(SPACE);
382                                    upName += " ";
383                            }
384                            else {
385                                    break _loop1938;
386                            }
387                            
388                    } while (true);
389                    }
390                    match(EQUALS);
391                    upName += "=";
392                    {
393                    _loop1940:
394                    do {
395                            if ((LA(1)==SPACE)) {
396                                    match(SPACE);
397                                    upName += " ";
398                            }
399                            else {
400                                    break _loop1940;
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                            _loop1951:
493                            do {
494                                    if ((LA(1)==SPACE)) {
495                                            match(SPACE);
496                                            value.trailingSpaces += " ";
497                                    }
498                                    else {
499                                            break _loop1951;
500                                    }
501                                    
502                            } while (true);
503                            }
504                            }
505                            break;
506                    }
507                    case EQUALS:
508                    case HYPHEN:
509                    case DIGIT:
510                    case ALPHA:
511                    case HEXPAIR:
512                    case ESC:
513                    case ESCESC:
514                    case UTFMB:
515                    case LUTF1_REST:
516                    {
517                            string(value);
518                            break;
519                    }
520                    case HEXVALUE:
521                    {
522                            {
523                            hexstring(value);
524                            {
525                            _loop1954:
526                            do {
527                                    if ((LA(1)==SPACE)) {
528                                            match(SPACE);
529                                            value.trailingSpaces += " ";
530                                    }
531                                    else {
532                                            break _loop1954;
533                                    }
534                                    
535                            } while (true);
536                            }
537                            }
538                            break;
539                    }
540                    case EOF:
541                    case COMMA:
542                    case PLUS:
543                    case SEMI:
544                    {
545                            break;
546                    }
547                    default:
548                    {
549                            throw new NoViableAltException(LT(1), getFilename());
550                    }
551                    }
552                    }
553            }
554            
555    /**
556         * RFC 4512 Section 1.4
557         *
558         * descr = keystring
559         * keystring = leadkeychar *keychar
560         * leadkeychar = ALPHA
561         * keychar = ALPHA / DIGIT / HYPHEN
562         *
563         */
564            public final String  descr() throws RecognitionException, TokenStreamException {
565                    String descr;
566                    
567                    Token  leadkeychar = null;
568                    Token  alpha = null;
569                    Token  digit = null;
570                    Token  hyphen = null;
571                    
572                    matchedProduction( "descr()" );
573                    
574                    
575                    leadkeychar = LT(1);
576                    match(ALPHA);
577                    descr = leadkeychar.getText();
578                    {
579                    _loop1945:
580                    do {
581                            switch ( LA(1)) {
582                            case ALPHA:
583                            {
584                                    alpha = LT(1);
585                                    match(ALPHA);
586                                    descr += alpha.getText();
587                                    break;
588                            }
589                            case DIGIT:
590                            {
591                                    digit = LT(1);
592                                    match(DIGIT);
593                                    descr += digit.getText();
594                                    break;
595                            }
596                            case HYPHEN:
597                            {
598                                    hyphen = LT(1);
599                                    match(HYPHEN);
600                                    descr += hyphen.getText();
601                                    break;
602                            }
603                            default:
604                            {
605                                    break _loop1945;
606                            }
607                            }
608                    } while (true);
609                    }
610                    return descr;
611            }
612            
613    /**
614         * RFC 4512 Section 1.4
615         *
616         * numericoid = number 1*( DOT number )
617         * number  = DIGIT / ( LDIGIT 1*DIGIT )
618         * DIGIT   = %x30 / LDIGIT       ; "0"-"9"
619         * LDIGIT  = %x31-39             ; "1"-"9"
620         *
621         */
622            public final String  numericoid() throws RecognitionException, TokenStreamException {
623                    String numericoid = "";
624                    
625                    Token  noid = null;
626                    
627                    matchedProduction( "numericoid()" );
628                    
629                    
630                    noid = LT(1);
631                    match(NUMERICOID);
632                    numericoid += noid.getText();
633                    return numericoid;
634            }
635            
636    /**
637         * RFC 2253, Section 3
638         *              / QUOTATION *( quotechar / pair ) QUOTATION ; only from v2
639         * quotechar     = <any character except "\" or QUOTATION >
640         *
641         */
642            public final void quotestring(
643                    UpAndNormValue value
644            ) throws RecognitionException, TokenStreamException {
645                    
646                    Token  dq1 = null;
647                    Token  s = null;
648                    Token  dq2 = null;
649                    
650                    matchedProduction( "quotestring()" );
651                    org.apache.directory.shared.ldap.util.ByteBuffer bb = new org.apache.directory.shared.ldap.util.ByteBuffer();
652                    byte[] bytes;
653                    
654                    
655                    {
656                    dq1 = LT(1);
657                    match(DQUOTE);
658                    value.upValue += dq1.getText();
659                    {
660                    _loop1960:
661                    do {
662                            switch ( LA(1)) {
663                            case COMMA:
664                            case EQUALS:
665                            case PLUS:
666                            case HYPHEN:
667                            case SEMI:
668                            case LANGLE:
669                            case RANGLE:
670                            case SPACE:
671                            case NUMERICOID_OR_ALPHA_OR_DIGIT:
672                            case NUMERICOID:
673                            case DOT:
674                            case NUMBER:
675                            case LDIGIT:
676                            case DIGIT:
677                            case ALPHA:
678                            case HEXPAIR_OR_ESCESC_OR_ESC:
679                            case HEX:
680                            case HEXVALUE_OR_SHARP:
681                            case HEXVALUE:
682                            case SHARP:
683                            case UTFMB:
684                            case LUTF1_REST:
685                            {
686                                    {
687                                    {
688                                    s = LT(1);
689                                    match(_tokenSet_0);
690                                    }
691                                    
692                                    value.upValue += s.getText();
693                                    bb.append( StringTools.getBytesUtf8( s.getText() ) ); 
694                                    
695                                    }
696                                    break;
697                            }
698                            case HEXPAIR:
699                            case ESC:
700                            case ESCESC:
701                            {
702                                    bytes=pair(value);
703                                    bb.append( bytes );
704                                    break;
705                            }
706                            default:
707                            {
708                                    break _loop1960;
709                            }
710                            }
711                    } while (true);
712                    }
713                    dq2 = LT(1);
714                    match(DQUOTE);
715                    value.upValue += dq2.getText();
716                    }
717                    
718                    // TODO: pair / s
719                    String string = StringTools.utf8ToString( bb.copyOfUsedBytes() );
720                    string = string.replace("\\ ", " ");
721                    value.normValue = string;
722                    
723            }
724            
725    /**
726         * RFC 4514 Section 3
727         *
728         * ; The following characters are to be escaped when they appear
729         * ; in the value to be encoded: ESC, one of <escaped>, leading
730         * ; SHARP or SPACE, trailing SPACE, and NULL.
731         * string =   [ ( leadchar / pair ) [ *( stringchar / pair )
732         *    ( trailchar / pair ) ] ]
733         *
734         * TODO: Trailing SPACE is manually removed. This needs review! 
735         * TODO: ESC SPACE is replaced by a simgle SPACE. This needs review! 
736         */
737            public final void string(
738                    UpAndNormValue value
739            ) throws RecognitionException, TokenStreamException {
740                    
741                    
742                    matchedProduction( "string()" );
743                    org.apache.directory.shared.ldap.util.ByteBuffer bb = new org.apache.directory.shared.ldap.util.ByteBuffer();
744                    String tmp;
745                    byte[] bytes;
746                    
747                    
748                    {
749                    {
750                    switch ( LA(1)) {
751                    case EQUALS:
752                    case HYPHEN:
753                    case DIGIT:
754                    case ALPHA:
755                    case LUTF1_REST:
756                    {
757                            tmp=lutf1();
758                            
759                            value.upValue += tmp;
760                            bb.append( StringTools.getBytesUtf8( tmp ) ); 
761                            
762                            break;
763                    }
764                    case UTFMB:
765                    {
766                            tmp=utfmb();
767                            
768                            value.upValue += tmp;
769                            bb.append( StringTools.getBytesUtf8( tmp ) );
770                            
771                            break;
772                    }
773                    case HEXPAIR:
774                    case ESC:
775                    case ESCESC:
776                    {
777                            bytes=pair(value);
778                            bb.append( bytes );
779                            break;
780                    }
781                    default:
782                    {
783                            throw new NoViableAltException(LT(1), getFilename());
784                    }
785                    }
786                    }
787                    {
788                    _loop1966:
789                    do {
790                            switch ( LA(1)) {
791                            case EQUALS:
792                            case HYPHEN:
793                            case SPACE:
794                            case DIGIT:
795                            case ALPHA:
796                            case SHARP:
797                            case LUTF1_REST:
798                            {
799                                    tmp=sutf1();
800                                    
801                                    value.upValue += tmp;
802                                    bb.append( StringTools.getBytesUtf8( tmp ) ); 
803                                    
804                                    break;
805                            }
806                            case UTFMB:
807                            {
808                                    tmp=utfmb();
809                                    
810                                    value.upValue += tmp;
811                                    bb.append( StringTools.getBytesUtf8( tmp ) ); 
812                                    
813                                    break;
814                            }
815                            case HEXPAIR:
816                            case ESC:
817                            case ESCESC:
818                            {
819                                    bytes=pair(value);
820                                    bb.append( bytes );
821                                    break;
822                            }
823                            default:
824                            {
825                                    break _loop1966;
826                            }
827                            }
828                    } while (true);
829                    }
830                    }
831                    
832                    String string = StringTools.utf8ToString( bb.copyOfUsedBytes() );
833                    
834                    // trim trailing space characters manually
835                    // don't know how to tell antlr that the last char mustn't be a space.
836                    int length = string.length();
837                    while ( length > 1 && string.charAt( length - 1 ) == ' ' && string.charAt( length - 2 ) != '\\' )
838                    {
839                    string = string.substring( 0, length - 1 );
840                    length = string.length();
841                    
842                    value.upValue = value.upValue.substring( 0, value.upValue.length() - 1 );
843                    value.trailingSpaces += " ";
844                    }
845                    string = string.replace("\\ ", " ");
846                    
847                    value.normValue = string;
848                    
849            }
850            
851    /**
852         * RFC 4514 Section 3
853         *
854         * hexstring = SHARP 1*hexpair
855         *
856         * If in <hexstring> form, a BER representation can be obtained from
857         * converting each <hexpair> of the <hexstring> to the octet indicated
858         * by the <hexpair>.
859         *
860         */
861            public final void hexstring(
862                    UpAndNormValue value
863            ) throws RecognitionException, TokenStreamException {
864                    
865                    Token  hexValue = null;
866                    
867                    matchedProduction( "hexstring()" );
868                    
869                    
870                    hexValue = LT(1);
871                    match(HEXVALUE);
872                    
873                    // convert to byte[]
874                    value.upValue = "#" + hexValue.getText();
875                    value.normValue = StringTools.toByteArray( hexValue.getText() ); 
876                    
877            }
878            
879    /**
880         * RFC 4514, Section 3
881         * pair = ESC ( ESC / special / hexpair )
882         * special = escaped / SPACE / SHARP / EQUALS
883         * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
884         * hexpair = HEX HEX
885         *
886         * If in <string> form, a LDAP string representation asserted value can
887         * be obtained by replacing (left to right, non-recursively) each <pair>
888         * appearing in the <string> as follows:
889         *   replace <ESC><ESC> with <ESC>;
890         *   replace <ESC><special> with <special>;
891         *   replace <ESC><hexpair> with the octet indicated by the <hexpair>.
892         * 
893         * RFC 2253, Section 3
894         * pair       = "\" ( special / "\" / QUOTATION / hexpair )
895         * special    = "," / "=" / "+" / "<" /  ">" / "#" / ";"
896         * 
897         * RFC 1779, Section 2.3
898         * <pair> ::= "\" ( <special> | "\" | '"')
899         * <special> ::= "," | "=" | <CR> | "+" | "<" |  ">"
900         *           | "#" | ";"
901         * 
902         * TODO: The ESC is removed from the norm value. This needs review! 
903         */
904            public final byte[]  pair(
905                    UpAndNormValue value
906            ) throws RecognitionException, TokenStreamException {
907                    byte[] pair;
908                    
909                    Token  hexpair = null;
910                    
911                    matchedProduction( "pair()" );
912                    String tmp;
913                    
914                    
915                    switch ( LA(1)) {
916                    case ESCESC:
917                    {
918                            {
919                            match(ESCESC);
920                            
921                            value.upValue += "\\\\";
922                            pair = StringTools.getBytesUtf8( "\\" );
923                            
924                            }
925                            break;
926                    }
927                    case ESC:
928                    {
929                            {
930                            match(ESC);
931                            value.upValue += "\\";
932                            tmp=special();
933                            
934                            value.upValue += tmp;
935                            pair = StringTools.getBytesUtf8( tmp ); 
936                            
937                            }
938                            break;
939                    }
940                    case HEXPAIR:
941                    {
942                            {
943                            hexpair = LT(1);
944                            match(HEXPAIR);
945                            
946                            value.upValue += "\\" + hexpair.getText(); 
947                            pair = StringTools.toByteArray( hexpair.getText() ); 
948                            
949                            }
950                            break;
951                    }
952                    default:
953                    {
954                            throw new NoViableAltException(LT(1), getFilename());
955                    }
956                    }
957                    return pair;
958            }
959            
960    /**
961     * RFC 4514, Section 3:
962     * LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A /
963     *    %x3D / %x3F-5B / %x5D-7F
964     *
965     * The rule LUTF1_REST doesn't contain the following charcters,
966     * so we must check them additionally
967     *   EQUALS (0x3D) 
968    -*   HYPHEN (0x2D)  
969     *   DIGIT (0x30-0x39)
970     *   ALPHA (0x41-0x5A and 0x61-0x7A)
971     */
972            public final String  lutf1() throws RecognitionException, TokenStreamException {
973                    String lutf1="";
974                    
975                    Token  rest = null;
976                    Token  equals = null;
977                    Token  hyphen = null;
978                    Token  digit = null;
979                    Token  alpha = null;
980                    
981                    matchedProduction( "lutf1()" );
982                    
983                    
984                    switch ( LA(1)) {
985                    case LUTF1_REST:
986                    {
987                            rest = LT(1);
988                            match(LUTF1_REST);
989                            lutf1 = rest.getText();
990                            break;
991                    }
992                    case EQUALS:
993                    {
994                            equals = LT(1);
995                            match(EQUALS);
996                            lutf1 = equals.getText();
997                            break;
998                    }
999                    case HYPHEN:
1000                    {
1001                            hyphen = LT(1);
1002                            match(HYPHEN);
1003                            lutf1 = hyphen.getText();
1004                            break;
1005                    }
1006                    case DIGIT:
1007                    {
1008                            digit = LT(1);
1009                            match(DIGIT);
1010                            lutf1 = digit.getText();
1011                            break;
1012                    }
1013                    case ALPHA:
1014                    {
1015                            alpha = LT(1);
1016                            match(ALPHA);
1017                            lutf1 = alpha.getText();
1018                            break;
1019                    }
1020                    default:
1021                    {
1022                            throw new NoViableAltException(LT(1), getFilename());
1023                    }
1024                    }
1025                    return lutf1;
1026            }
1027            
1028            public final String  utfmb() throws RecognitionException, TokenStreamException {
1029                    String utfmb;
1030                    
1031                    Token  s = null;
1032                    
1033                    matchedProduction( "utfmb()" );
1034                    
1035                    
1036                    s = LT(1);
1037                    match(UTFMB);
1038                    utfmb = s.getText();
1039                    return utfmb;
1040            }
1041            
1042    /**
1043     * RFC 4514, Section 3:
1044     * SUTF1 = %x01-21 / %x23-2A / %x2D-3A /
1045     *    %x3D / %x3F-5B / %x5D-7F
1046     *
1047     * The rule LUTF1_REST doesn't contain the following charcters,
1048     * so we must check them additionally
1049     *   EQUALS (0x3D) 
1050    -*   HYPHEN (0x2D)  
1051     *   DIGIT (0x30-0x39)
1052     *   ALPHA (0x41-0x5A and 0x61-0x7A)
1053     *   SHARP
1054     *   SPACE
1055     */
1056            public final String  sutf1() throws RecognitionException, TokenStreamException {
1057                    String sutf1="";
1058                    
1059                    Token  rest = null;
1060                    Token  equals = null;
1061                    Token  hyphen = null;
1062                    Token  digit = null;
1063                    Token  alpha = null;
1064                    Token  sharp = null;
1065                    Token  space = null;
1066                    
1067                    matchedProduction( "sutf1()" );
1068                    
1069                    
1070                    switch ( LA(1)) {
1071                    case LUTF1_REST:
1072                    {
1073                            rest = LT(1);
1074                            match(LUTF1_REST);
1075                            sutf1 = rest.getText();
1076                            break;
1077                    }
1078                    case EQUALS:
1079                    {
1080                            equals = LT(1);
1081                            match(EQUALS);
1082                            sutf1 = equals.getText();
1083                            break;
1084                    }
1085                    case HYPHEN:
1086                    {
1087                            hyphen = LT(1);
1088                            match(HYPHEN);
1089                            sutf1 = hyphen.getText();
1090                            break;
1091                    }
1092                    case DIGIT:
1093                    {
1094                            digit = LT(1);
1095                            match(DIGIT);
1096                            sutf1 = digit.getText();
1097                            break;
1098                    }
1099                    case ALPHA:
1100                    {
1101                            alpha = LT(1);
1102                            match(ALPHA);
1103                            sutf1 = alpha.getText();
1104                            break;
1105                    }
1106                    case SHARP:
1107                    {
1108                            sharp = LT(1);
1109                            match(SHARP);
1110                            sutf1 = sharp.getText();
1111                            break;
1112                    }
1113                    case SPACE:
1114                    {
1115                            space = LT(1);
1116                            match(SPACE);
1117                            sutf1 = space.getText();
1118                            break;
1119                    }
1120                    default:
1121                    {
1122                            throw new NoViableAltException(LT(1), getFilename());
1123                    }
1124                    }
1125                    return sutf1;
1126            }
1127            
1128    /**
1129         * RFC 4514 Section 3
1130         * 
1131         * special = escaped / SPACE / SHARP / EQUALS
1132         * escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
1133         *
1134         * TODO: For space an ESC is manually added. This needs review! 
1135         */
1136            public final String  special() throws RecognitionException, TokenStreamException {
1137                    String special;
1138                    
1139                    Token  dquote = null;
1140                    Token  plus = null;
1141                    Token  comma = null;
1142                    Token  semi = null;
1143                    Token  langle = null;
1144                    Token  rangle = null;
1145                    Token  space = null;
1146                    Token  sharp = null;
1147                    Token  equals = null;
1148                    
1149                    matchedProduction( "special()" );
1150                    
1151                    
1152                    {
1153                    switch ( LA(1)) {
1154                    case DQUOTE:
1155                    {
1156                            dquote = LT(1);
1157                            match(DQUOTE);
1158                            special = dquote.getText();
1159                            break;
1160                    }
1161                    case PLUS:
1162                    {
1163                            plus = LT(1);
1164                            match(PLUS);
1165                            special = plus.getText();
1166                            break;
1167                    }
1168                    case COMMA:
1169                    {
1170                            comma = LT(1);
1171                            match(COMMA);
1172                            special = comma.getText();
1173                            break;
1174                    }
1175                    case SEMI:
1176                    {
1177                            semi = LT(1);
1178                            match(SEMI);
1179                            special = semi.getText();
1180                            break;
1181                    }
1182                    case LANGLE:
1183                    {
1184                            langle = LT(1);
1185                            match(LANGLE);
1186                            special = langle.getText();
1187                            break;
1188                    }
1189                    case RANGLE:
1190                    {
1191                            rangle = LT(1);
1192                            match(RANGLE);
1193                            special = rangle.getText();
1194                            break;
1195                    }
1196                    case SPACE:
1197                    {
1198                            space = LT(1);
1199                            match(SPACE);
1200                            special = "\\" + space.getText();
1201                            break;
1202                    }
1203                    case SHARP:
1204                    {
1205                            sharp = LT(1);
1206                            match(SHARP);
1207                            special = sharp.getText();
1208                            break;
1209                    }
1210                    case EQUALS:
1211                    {
1212                            equals = LT(1);
1213                            match(EQUALS);
1214                            special = equals.getText();
1215                            break;
1216                    }
1217                    default:
1218                    {
1219                            throw new NoViableAltException(LT(1), getFilename());
1220                    }
1221                    }
1222                    }
1223                    return special;
1224            }
1225            
1226            
1227            public static final String[] _tokenNames = {
1228                    "<0>",
1229                    "EOF",
1230                    "<2>",
1231                    "NULL_TREE_LOOKAHEAD",
1232                    "COMMA",
1233                    "EQUALS",
1234                    "PLUS",
1235                    "HYPHEN",
1236                    "DQUOTE",
1237                    "SEMI",
1238                    "LANGLE",
1239                    "RANGLE",
1240                    "SPACE",
1241                    "NUMERICOID_OR_ALPHA_OR_DIGIT",
1242                    "NUMERICOID",
1243                    "DOT",
1244                    "NUMBER",
1245                    "LDIGIT",
1246                    "DIGIT",
1247                    "ALPHA",
1248                    "HEXPAIR_OR_ESCESC_OR_ESC",
1249                    "HEXPAIR",
1250                    "ESC",
1251                    "ESCESC",
1252                    "HEX",
1253                    "HEXVALUE_OR_SHARP",
1254                    "HEXVALUE",
1255                    "SHARP",
1256                    "UTFMB",
1257                    "LUTF1_REST"
1258            };
1259            
1260            private static final long[] mk_tokenSet_0() {
1261                    long[] data = { 1059061488L, 0L, 0L, 0L};
1262                    return data;
1263            }
1264            public static final BitSet _tokenSet_0 = new BitSet(mk_tokenSet_0());
1265            
1266            }