Methods Summary |
---|
private boolean | IsEscapableChar(int theChar, java.lang.String escapableChars)
return( escapableChars.indexOf( theChar ) >= 0 || theChar == mParseChars.mEscapeChar );
|
public ParseResult[] | Parse(java.lang.String input, boolean namedArgs)
mNamedArgs = namedArgs;
mInput = input;
mCurIndex = 0;
final ArrayList results = new ArrayList();
while ( inputRemainingCount() > 0 )
{
final ParseResult nextArg = ParseArg( );
assert( nextArg != null );
results.add( nextArg );
}
final ParseResult [] arrayResults = new ParseResult [ results.size( ) ];
results.toArray( arrayResults );
return( arrayResults );
|
private ParseResult | ParseArg()
checkInputAvailable();
ParseResult result = null;
if ( mNamedArgs )
{
result = ParseNamedArg();
}
else
{
result = ParseNonNamedArg( "" + mParseChars.mArgDelim );
}
return( result );
|
private ParseResult | ParseArray()
checkInputAvailable();
// verify that it's an array
int theChar = nextLiteralChar();
if ( theChar != mParseChars.mArrayLeft )
{
backup( 1 );
return( null );
}
final ArrayList elems = new ArrayList();
boolean endOfArrayFound = false;
if ( peekNextLiteralChar() == mParseChars.mArrayRight )
{
// empty array
endOfArrayFound = true;
advance( 1 );
}
else
{
while ( (theChar = peekNextLiteralChar( )) > 0 )
{
final ParseResult elem = ParseNonNamedArg( "" +
mParseChars.mArrayRight + mParseChars.mArgDelim );
elems.add( elem );
backup( 1 );
if ( nextLiteralChar() == mParseChars.mArrayRight)
{
endOfArrayFound = true;
break;
}
}
}
if ( ! endOfArrayFound )
{
throw new ArgParserException( "end of array not found" );
}
final ParseResult [] resultsArray = new ParseResult[ elems.size() ];
elems.toArray( resultsArray );
final ParseResult result = new ParseResult( ParseResult.ARRAY, resultsArray );
return( result );
|
private ParseResult | ParseLiteralString()
checkInputAvailable();
// verify that it's a literal string
int theChar = nextLiteralChar();
if ( theChar != mParseChars.LITERAL_STRING_DELIM )
{
backup( 1 );
return( null );
}
final StringBuffer buf = new StringBuffer();
boolean endOfStringFound = false;
while ( (theChar = peekNextLiteralChar( )) > 0 )
{
if ( theChar == mParseChars.LITERAL_STRING_DELIM )
{
endOfStringFound = true;
advance( 1 );
break;
}
theChar = nextChar( mParseChars.mEscapeChar, mParseChars.mEscapableCharsWithinLiteralString );
buf.append( (char)theChar );
}
if ( ! endOfStringFound )
{
throw new ArgParserException( "literal string must be terminated by double quote \"" );
}
final String resultString = new String( buf );
final ParseResult result = new ParseResult( ParseResult.LITERAL_STRING, resultString );
return( result );
|
private ParseResult | ParseNamedArg()
checkInputAvailable();
final String name = ParseNamedArgName();
ParseResult result = null;
// special case--no more input
if ( inputRemainingCount() > 0 )
{
result = ParseNonNamedArg( "" + mParseChars.mArgDelim );
}
else
{
result = new ParseResult( ParseResult.OTHER, "");
}
result.setName( name );
return( result );
|
private java.lang.String | ParseNamedArgName()
checkInputAvailable();
final StringBuffer buf = new StringBuffer();
boolean foundDelim = false;
int theChar = 0;
while ( (theChar = nextLiteralChar()) > 0 )
{
if ( theChar == mParseChars.ARG_VALUE_DELIM )
{
foundDelim = true;
break;
}
if ( ! Character.isJavaIdentifierPart( (char)theChar ) )
{
break;
}
buf.append( (char)theChar );
}
if ( ! foundDelim )
{
throw new ArgParserException(
"named arguments must be of the form name=value: " + buf.toString() );
}
return( new String( buf ) );
|
public java.lang.String[] | ParseNames(java.lang.String input)
mInput = input;
mCurIndex = 0;
final ArrayList list = new ArrayList();
StringBuffer buf = new StringBuffer();
while ( true )
{
final int theChar = nextLiteralChar();
if ( theChar < 0 || theChar == mParseChars.mArgDelim )
{
list.add( new String( buf ) );
buf.setLength( 0 );
if ( theChar < 0 )
break;
}
else
{
buf.append( (char)theChar );
}
}
final String [] results = (String [])list.toArray( new String [ list.size() ]);
return( results );
|
private ParseResult | ParseNonNamedArg(java.lang.String delimiters)
ParseResult result = null;
String typeCast = ParseTypeCast(); // may be null--that's OK
if ( isStringTypecast( typeCast ) )
{
if ( inputRemainingCount() == 0 )
{
// special case--a type cast followed by nothing is OK as an empty string
result = new ParseResult( ParseResult.LITERAL_STRING, "" );
result.setTypeCast( typeCast );
return( result );
}
}
boolean quotedString = false;
result = ParseLiteralString();
if ( result != null )
{
// if a string X is quoted as "X" , this is equivalent (shorthand) for (String)X
typeCast = "String";
quotedString = true;
}
else
{
result = ParseArray();
if ( result == null )
{
result = ParseRegular( delimiters );
}
}
result.setTypeCast( typeCast );
if ( isStringTypecast( typeCast ) && result.getType() != ParseResult.ARRAY )
{
result.setType( ParseResult.LITERAL_STRING );
if ( (! quotedString) &&
result.getData() instanceof String &&
"null".equalsIgnoreCase( (String)result.getData() ) )
{
result.setData( null );
}
}
// eat the delimiter
final int theChar = nextLiteralChar();
boolean validDelimiter = delimiters.indexOf( theChar ) >= 0 || theChar < 0;
if ( ! validDelimiter )
{
throw new ArgParserException( "Syntax error: parsed this so far: " + mInput.substring( 1, mCurIndex ) );
}
return( result );
|
private ParseResult | ParseRegular(java.lang.String delimiters)
checkInputAvailable();
final StringBuffer buf = new StringBuffer();
int theChar;
while ( (theChar = peekNextLiteralChar() ) > 0 )
{
if ( delimiters.indexOf( theChar ) >= 0 )
{
break;
}
theChar = nextChar();
buf.append( (char)theChar );
}
final String resultString = new String( buf );
final ParseResult result = new ParseResult( ParseResult.OTHER, resultString );
return( result );
|
private java.lang.String | ParseTypeCast()
int theChar = nextLiteralChar();
if ( theChar != mParseChars.TYPECAST_BEGIN )
{
backup( 1 );
return( null );
}
final StringBuffer buf = new StringBuffer();
theChar = nextLiteralChar();
if ( ! Character.isJavaIdentifierStart( (char)theChar ) )
{
final String msg = "type cast must contain a legal Java " +
"identifier start character: " + peekRemaining();
throw new ArgParserException( msg );
}
buf.append( (char)theChar );
boolean foundDelim = false;
while ( (theChar = nextLiteralChar( )) > 0 )
{
if ( theChar == mParseChars.TYPECAST_END )
{
foundDelim = true;
break;
}
if ( theChar != '." && ! Character.isJavaIdentifierPart( (char)theChar ) )
{
throw new ArgParserException( "type cast must contain a legal Java identifier part: " +
(char)theChar );
}
buf.append( (char)theChar );
}
if ( ! foundDelim )
{
throw new ArgParserException( "type cast must be terminated by the ) character" );
}
final String result = new String( buf );
if ( result.length() == 0 )
{
throw new ArgParserException( "type cast must contain a type" );
}
return( result );
|
private void | advance(int count)
assert( count <= inputRemainingCount() );
mCurIndex += count;
|
private void | backup(int count)
assert( count <= mCurIndex );
mCurIndex -= count;
|
private void | checkInputAvailable()
if ( inputRemainingCount() == 0 )
{
throw new ArgParserException( "expecting additional input" );
}
|
private int | escapeCharToChar(int theChar)
int result = -1;
if ( theChar == 'n" )
result = '\n";
else if ( theChar == 'r" )
result = '\r";
else if ( theChar == 't" )
result = '\t";
else
result = theChar;
return( result );
|
private int | inputRemainingCount()
return( mInput.length() - mCurIndex );
|
private static boolean | isDigit(int theChar)
return( (theChar >= '0" && theChar <= '9") );
|
private static boolean | isHexDigit(int theChar)
return( isDigit( theChar ) || (theChar >= 'a" && theChar <= 'f") ||
(theChar >= 'A" && theChar <= 'F") );
|
boolean | isStringTypecast(java.lang.String typecast)
return( typecast != null &&
(typecast.equals( "String" ) || typecast.equals( "java.lang.String" ) ) );
|
private int | nextChar(int escapeChar, java.lang.String escapableChars)
int result = -1;
final int theChar = nextLiteralChar();
if ( theChar == escapeChar )
{
final int theNextChar = nextLiteralChar();
if ( IsEscapableChar( theNextChar, escapableChars ) )
{
result = escapeCharToChar( theNextChar );
}
else
{
// if valid hexadecimal, convert two hex digits to a number
// otherwise emit the escape char and restart
// should we allow unicode?
result = escapeChar;
if ( isHexDigit( theNextChar ) && peekNextLiteralChar() > 0 )
{
final int theNextNextChar = nextLiteralChar();
if ( isHexDigit( theNextNextChar ) )
{
result = (((int)theNextChar) << 4) + (int)theNextNextChar;
}
}
else
{
backup( 1 );
}
}
}
else
{
result = theChar;
}
return( result );
|
private int | nextChar()
return( nextChar( mParseChars.mEscapeChar, mParseChars.mEscapableChars ) );
|
private int | nextLiteralChar()
final int result = peekNextLiteralChar();
if ( result > 0 )
{
advance( 1 );
}
return( result );
|
private static void | p(java.lang.Object o)
System.out.println( o.toString() );
|
private int | peekNextLiteralChar()
if ( inputRemainingCount() <= 0 )
return( -1 );
final char result = mInput.charAt( mCurIndex );
return( result );
|
private java.lang.String | peekRemaining()
if ( inputRemainingCount() <= 0 )
return( "" );
return( mInput.substring( mCurIndex, mInput.length() ) );
|