blob: 87e9c13e5dfd94e04a7743578b757fedf4ac28a1 [file]
// ============================================================================
//
//
// OpenLDAP Schema Parser
//
//
// ============================================================================
// $Rev$
// ============================================================================
header {
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* Keep the semicolon right next to the package name or else there will be a
* bug that comes into the foreground in the new antlr release.
*/
package org.apache.ldap.server.tools.schema;
import java.util.* ;
import org.apache.ldap.common.schema.*;
}
class antlrOpenLdapSchemaLexer extends Lexer ;
options {
k = 7 ;
exportVocab=antlrOpenLdapSchema ;
charVocabulary = '\3'..'\377' ;
caseSensitive = false ;
//testLiterals = true ;
defaultErrorHandler = false ;
}
WS : ( '#' (~'\n')* '\n' { newline(); }
| ' '
| '\t'
| '\r' '\n' { newline(); }
| '\n' { newline(); }
| '\r' { newline(); }
)
{$setType(Token.SKIP);} //ignore this token
;
QUOTE : '\''
;
DIGIT : '0' .. '9'
;
DOLLAR : '$'
;
OPEN_PAREN : '('
;
CLOSE_PAREN : ')'
;
OPEN_BRACKET : '{'
;
CLOSE_BRACKET : '}'
;
protected NUMERIC_STRING : ('0' .. '9')+
;
NUMERICOID :
NUMERIC_STRING ( '.' NUMERIC_STRING )+
;
IDENTIFIER options { testLiterals=true; }
:
( 'a' .. 'z') ( 'a' .. 'z' | '0' .. '9' | '-' | ';' )*
;
DESC
:
"desc" WS QUOTE ( ~'\'' )+ QUOTE
;
SYNTAX
:
"syntax" WS NUMERICOID ( OPEN_BRACKET ( DIGIT )+ CLOSE_BRACKET )?
;
class antlrOpenLdapSchemaParser extends Parser ;
options {
k = 5 ;
defaultErrorHandler = false ;
}
{
public static final String[] EMPTY = new String[0];
private Map attributeTypes = new HashMap();
private Map objectClasses = new HashMap();
private ParserMonitor monitor = null;
// ------------------------------------------------------------------------
// Public Methods
// ------------------------------------------------------------------------
public void clear()
{
attributeTypes.clear();
objectClasses.clear();
}
public Map getAttributeTypes()
{
return Collections.unmodifiableMap( attributeTypes );
}
public Map getObjectClasses()
{
return Collections.unmodifiableMap( objectClasses );
}
public void setParserMonitor( ParserMonitor monitor )
{
this.monitor = monitor;
}
// ------------------------------------------------------------------------
// Private Methods
// ------------------------------------------------------------------------
private void matchedProduction( String msg )
{
if ( null != monitor )
{
monitor.matchedProduction( msg );
}
}
}
// ----------------------------------------------------------------------------
// Main Entry Point Production
// ----------------------------------------------------------------------------
parseSchema
{
}
:
( attributeType | objectClass )* "END"
;
// ----------------------------------------------------------------------------
// AttributeType Productions
// ----------------------------------------------------------------------------
objectClass
{
matchedProduction( "objectClass()" );
ObjectClassLiteral objectClass = null;
}
:
"objectclass"
OPEN_PAREN oid:NUMERICOID
{
objectClass = new ObjectClassLiteral( oid.getText() );
}
( objectClassNames[objectClass] )?
( objectClassDesc[objectClass] )?
( "OBSOLETE" { objectClass.setObsolete( true ); } )?
( objectClassSuperiors[objectClass] )?
(
"ABSTRACT" { objectClass.setClassType( ObjectClassTypeEnum.ABSTRACT ); } |
"STRUCTURAL" { objectClass.setClassType( ObjectClassTypeEnum.STRUCTURAL ); } |
"AUXILIARY" { objectClass.setClassType( ObjectClassTypeEnum.AUXILIARY ); }
)?
( must[objectClass] )?
( may[objectClass] )?
CLOSE_PAREN
{
objectClasses.put( objectClass.getOid(), objectClass );
}
;
may [ObjectClassLiteral objectClass]
{
matchedProduction( "may(ObjectClassLiteral)" ) ;
ArrayList list = null;
}
: "MAY" list=woidlist
{
objectClass.setMay( ( String[] ) list.toArray( EMPTY ) );
}
;
must [ObjectClassLiteral objectClass]
{
matchedProduction( "must(ObjectClassLiteral)" ) ;
ArrayList list = null;
}
: "MUST" list=woidlist
{
objectClass.setMust( ( String[] ) list.toArray( EMPTY ) );
}
;
objectClassSuperiors [ObjectClassLiteral objectClass]
{
matchedProduction( "objectClassSuperiors(ObjectClassLiteral)" ) ;
ArrayList list = null;
}
: "SUP" list=woidlist
{
objectClass.setSuperiors( ( String[] ) list.toArray( EMPTY ) );
}
;
woid returns [String oid]
{
oid = null;
matchedProduction( "woid()" ) ;
}
:
(
opt1:NUMERICOID
{
oid = opt1.getText();
}
|
opt2:IDENTIFIER
{
oid = opt2.getText();
}
)
;
woidlist returns [ArrayList list]
{
matchedProduction( "woidlist()" ) ;
list = new ArrayList( 2 );
String oid = null;
}
:
(
oid=woid { list.add( oid ); } |
(
OPEN_PAREN
oid=woid { list.add( oid ); } ( DOLLAR oid=woid { list.add( oid ); } )*
CLOSE_PAREN
)
)
;
objectClassDesc [ObjectClassLiteral objectClass]
{
matchedProduction( "desc(ObjectClassLiteral)" ) ;
}
: d:DESC
{
String desc = d.getText().split( "'" )[1];
String[] quoted = desc.split( "\"" );
if ( quoted.length == 1 )
{
objectClass.setDescription( desc );
}
else
{
StringBuffer buf = new StringBuffer();
for ( int ii = 0; ii < quoted.length; ii++ )
{
if ( ii < quoted.length - 1 )
{
buf.append( quoted[ii] ).append( "\\" ).append( "\"" );
}
else
{
buf.append( quoted[ii] );
}
}
objectClass.setDescription( buf.toString() );
}
}
;
objectClassNames [ObjectClassLiteral objectClass]
{
matchedProduction( "names(ObjectClassLiteral)" ) ;
ArrayList list = new ArrayList();
}
:
(
"NAME"
( QUOTE id0:IDENTIFIER QUOTE
{
list.add( id0.getText() );
}
|
( OPEN_PAREN QUOTE id1:IDENTIFIER
{
list.add( id1.getText() );
} QUOTE
( QUOTE id2:IDENTIFIER QUOTE
{
list.add( id2.getText() );
} )* CLOSE_PAREN )
)
)
{
objectClass.setNames( ( String[] ) list.toArray( EMPTY ) );
}
;
// ----------------------------------------------------------------------------
// AttributeType Productions
// ----------------------------------------------------------------------------
attributeType
{
matchedProduction( "attributeType()" );
AttributeTypeLiteral type = null;
}
:
"attributetype"
OPEN_PAREN oid:NUMERICOID
{
type = new AttributeTypeLiteral( oid.getText() );
}
( names[type] )?
( desc[type] )?
( "OBSOLETE" { type.setObsolete( true ); } )?
( superior[type] )?
( equality[type] )?
( ordering[type] )?
( substr[type] )?
( syntax[type] )?
( "SINGLE-VALUE" { type.setSingleValue( true ); } )?
( "COLLECTIVE" { type.setCollective( true ); } )?
( "NO-USER-MODIFICATION" { type.setNoUserModification( true ); } )?
( usage[type] )?
CLOSE_PAREN
{
attributeTypes.put( type.getOid(), type );
}
;
desc [AttributeTypeLiteral type]
{
matchedProduction( "desc(AttributeTypeLiteral)" ) ;
}
: d:DESC
{
String desc = d.getText().split( "'" )[1];
String[] quoted = desc.split( "\"" );
if ( quoted.length == 1 )
{
type.setDescription( desc );
}
else
{
StringBuffer buf = new StringBuffer();
for ( int ii = 0; ii < quoted.length; ii++ )
{
if ( ii < quoted.length - 1 )
{
buf.append( quoted[ii] ).append( "\\" ).append( "\"" );
}
else
{
buf.append( quoted[ii] );
}
}
type.setDescription( buf.toString() );
}
}
;
superior [AttributeTypeLiteral type]
{
matchedProduction( "superior(AttributeTypeLiteral)" ) ;
}
: "SUP"
(
oid:NUMERICOID
{
type.setSuperior( oid.getText() );
}
|
id:IDENTIFIER
{
type.setSuperior( id.getText() );
}
);
equality [AttributeTypeLiteral type]
{
matchedProduction( "equality(AttributeTypeLiteral)" ) ;
}
: "EQUALITY"
(
oid:NUMERICOID
{
type.setEquality( oid.getText() );
}
|
id:IDENTIFIER
{
type.setEquality( id.getText() );
}
);
substr [AttributeTypeLiteral type]
{
matchedProduction( "substr(AttributeTypeLiteral)" ) ;
}
: "SUBSTR"
(
oid:NUMERICOID
{
type.setSubstr( oid.getText() );
}
|
id:IDENTIFIER
{
type.setSubstr( id.getText() );
}
);
ordering [AttributeTypeLiteral type]
{
matchedProduction( "ordering(AttributeTypeLiteral)" ) ;
}
: "ORDERING"
(
oid:NUMERICOID
{
type.setOrdering( oid.getText() );
}
|
id:IDENTIFIER
{
type.setOrdering( id.getText() );
}
);
names [AttributeTypeLiteral type]
{
matchedProduction( "names(AttributeTypeLiteral)" ) ;
ArrayList list = new ArrayList();
}
:
"NAME"
(
QUOTE id0:IDENTIFIER QUOTE { list.add( id0.getText() ); } |
( OPEN_PAREN
( QUOTE id1:IDENTIFIER
{
list.add( id1.getText() );
}
QUOTE
)+
CLOSE_PAREN )
)
{
type.setNames( ( String[] ) list.toArray( EMPTY ) );
}
;
syntax [AttributeTypeLiteral type]
{
matchedProduction( "syntax(AttributeTypeLiteral)" ) ;
}
: token:SYNTAX
{
String[] comps = token.getText().split( " " );
int index = comps[1].indexOf( "{" );
if ( index == -1 )
{
type.setSyntax( comps[1] );
return;
}
String oid = comps[1].substring( 0, index );
String length = comps[1].substring( index + 1, comps[1].length() - 1 );
type.setSyntax( oid );
type.setLength( Integer.parseInt( length ) );
}
;
usage [AttributeTypeLiteral type]
{
matchedProduction( "usage(AttributeTypeLiteral)" ) ;
}
:
"USAGE"
(
"userApplications" { type.setUsage( UsageEnum.USERAPPLICATIONS ); } |
"directoryOperation" { type.setUsage( UsageEnum.DIRECTORYOPERATION ); } |
"distributedOperation" { type.setUsage( UsageEnum.DISTRIBUTEDOPERATION ); } |
"dSAOperation" { type.setUsage( UsageEnum.DSAOPERATION ); }
);