?? macrotable.java
字號:
if (result == null)
return null;
else
return result.toString();
}
//----------------------------------------------------------------------------------------------
/**
* Determines if this macro has got replacement text or is just a defined symbol.
*
* @return <b>true</b> if there is replacement text, <b>false</b> if it is only a symbol.
*/
public boolean isEmpty()
{
return (substitution != null && substitution.length() > 0);
}
//----------------------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------------------------
/**
* This private class serves as convenience class for setting up a tokenizer.
*/
private class MacroTokenizer
{
private Reader reader;
private StreamTokenizer tokenizer;
//----------------------------------------------------------------------------------------------
/**
* Constructor for the tokenizer that takes a string as input.
*
* @param input The input.
* @param numberSignSeparate Determines if number signs (#) are treated separately or as part
* of an identifier.
*/
public MacroTokenizer(String input, boolean numberSignSeparate)
{
reader = new StringReader(input);
tokenizer = new StreamTokenizer(reader);
tokenizer.resetSyntax();
tokenizer.lowerCaseMode(false);
tokenizer.slashSlashComments(true);
tokenizer.slashStarComments(true);
tokenizer.wordChars('a', 'z');
tokenizer.wordChars('A', 'Z');
tokenizer.wordChars('_', '_');
tokenizer.wordChars('0', '9');
// Add the number sign as word char too. In our context it can only appear as part of
// a preprocessor definition, which never can be a macro.
if (!numberSignSeparate)
tokenizer.wordChars('#', '#');
}
//----------------------------------------------------------------------------------------------
/**
* Scans the characters between two quote chars and returns them (without the quotes).
*
* @param quoteChar The character to use for end recognition.
* @return The scanned string literal.
*/
private String readString(char quoteChar)
{
StringBuffer buffer = new StringBuffer();
boolean skipNext = false;
do
{
char c = 0;
try
{
c = (char)reader.read();
}
catch (IOException e)
{
e.printStackTrace();
}
if (c == '\uFFFF')
break;
if (skipNext)
{
skipNext = false;
buffer.append(c);
continue;
}
if (c == '\\')
skipNext = true;
else
if (c == quoteChar)
break;
buffer.append(c);
}
while (true);
return buffer.toString();
}
//----------------------------------------------------------------------------------------------
/**
* This method extracts text between two parentheses (also with nesting) and must only be
* called if the current token is an opening parenthesis. In this process no token retrieval
* takes place but instead characters are read directly from the input.
*
* @return The text between the parentheses.
*/
public String getInnerText()
{
int level = 1;
StringBuffer buffer = new StringBuffer();
do
{
char c = 0;
try
{
c = (char) reader.read();
}
catch (IOException e)
{
// Since we are reading from a string there can never be an IOException.
// However rules are to have code for the exception, regardless of whether it appears or not.
e.printStackTrace();
}
if (c == '\uFFFF')
reportError("Unexpected end of input.");
if (c == '(')
level++;
else
if (c == ')')
level--;
// The level tracker becomes 0 when the end of the list was found.
if (level == 0)
break;
buffer.append(c);
}
while (true);
return buffer.toString();
}
//----------------------------------------------------------------------------------------------
/**
* Returns the current token as numeric value. This is only valid if the current token
* is TT_NUMERAL.
*
* @return The numeric value.
*/
public double getNumericValue()
{
return tokenizer.nval;
}
//----------------------------------------------------------------------------------------------
/**
* Reads from the current input position up to count characters without tokenizing them and
* returns the substring. Escape sequences are converted, too.
*
* @param count The number of characters to read. This can also be a very high value to indicate
* that everything remaining on the input should be returned.
* @return The substring with a length of either <b>count</b> or the remaining number of input
* characters, whichever is smaller.
*/
public String getRawInput(int count)
{
StringBuffer buffer = new StringBuffer();
while (count > 0)
{
char c = 0;
try
{
c = (char) reader.read();
// Convert escape sequence.
if (c == '\\')
{
c = (char) reader.read();
if(c == 'u')
{
// Read the xxxx.
int value = 0;
for (int i = 0; i < 4; i++)
{
c = (char) reader.read();
switch (c)
{
case '0': case '1': case '2': case '3': case '4':case '5':
case '6': case '7': case '8': case '9':
{
value = (value << 4) + c - '0';
break;
}
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
{
value = (value << 4) + 10 + c - 'a';
break;
}
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
{
value = (value << 4) + 10 + c - 'A';
break;
}
default:
{
throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
}
}
}
c = (char) value;
}
else
{
switch (c)
{
case 'a':
{
c = 0x7;
break;
}
case 'b':
{
c = '\b';
break;
}
case 'f':
{
c = 0xC;
break;
}
case 'n':
{
c = '\n';
break;
}
case 'r':
{
c = '\r';
break;
}
case 't':
{
c = '\t';
break;
}
case 'v':
{
c = 0xB;
break;
}
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
if (c == '\uFFFF')
break;
buffer.append(c);
}
return buffer.toString();
}
//----------------------------------------------------------------------------------------------
/**
* Returns the current token as string value. If the current token is a quote char then
* the text included in the quotes is returned instead.
*
* @return The string value.
*/
public String getStringValue()
{
String result = "";
switch (tokenizer.ttype)
{
case StreamTokenizer.TT_WORD:
{
result = tokenizer.sval;
break;
}
case '"':
{
// Note: we cannot use the built-in feature of StreamTokenizer for strings as it
// tries to be too smart and converts all escape sequences to characters.
// This conflicts however with the following parser stage. Hence we do a raw scan
// on the underlying input stream.
result = readString('"');
break;
}
case '\'':
{
// See note for double quote case.
result = readString('\'');
break;
}
}
return result;
}
//----------------------------------------------------------------------------------------------
/**
* Returns the next token from the internal tokenizer.
*
* @return The next token.
*/
public int nextToken()
{
try
{
return tokenizer.nextToken();
}
catch (IOException e)
{
// Since we are reading from a string there can never be an IOException.
// However rules are to have code for the exception, regardless of whether it appears or not.
e.printStackTrace();
return StreamTokenizer.TT_EOF;
}
}
//----------------------------------------------------------------------------------------------
/**
* Helper method to undo the last nextToken() call.
*/
public void pushBack()
{
tokenizer.pushBack();
}
//----------------------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------------------------
protected void doEvent(int event, String message)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -