1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

Update to Scanner2.

This commit is contained in:
Doug Schaefer 2004-06-15 03:37:56 +00:00
parent 7f8eb9fbd2
commit b4fd69965f
2 changed files with 178 additions and 15 deletions

View file

@ -373,7 +373,6 @@ public class Scanner2Test extends BaseScanner2Test
{
initializeScanner("#define SYMBOL 5\n#ifdef SYMBOL\nint counter(SYMBOL);\n#endif"); //$NON-NLS-1$
validateToken(IToken.t_int);
validateIdentifier("counter"); //$NON-NLS-1$
validateToken(IToken.tLPAREN);
@ -397,7 +396,6 @@ public class Scanner2Test extends BaseScanner2Test
initializeScanner("#ifndef DEFINED\n#define DEFINED 100\n#endif\nint count = DEFINED;"); //$NON-NLS-1$
scanner.addDefinition("DEFINED", "101"); //$NON-NLS-1$ //$NON-NLS-2$
validateDefinition("DEFINED", "101"); //$NON-NLS-1$ //$NON-NLS-2$
validateToken(IToken.t_int);
validateIdentifier("count"); //$NON-NLS-1$
@ -490,7 +488,24 @@ public class Scanner2Test extends BaseScanner2Test
validateDefinition("ONE", "1"); //$NON-NLS-1$ //$NON-NLS-2$
validateDefinition("TWO", "ONE + ONE"); //$NON-NLS-1$ //$NON-NLS-2$
initializeScanner("#ifndef ONE\n# define ONE 1\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#else\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#endif\n"); //$NON-NLS-1$
initializeScanner(
"#ifndef ONE\n" +
"# define ONE 1\n" +
"# ifndef TWO\n" +
"# define TWO ONE + ONE \n" +
"# else\n" +
"# undef TWO\n" +
"# define TWO 2 \n" +
"# endif\n" +
"#else\n" +
"# ifndef TWO\n" +
"# define TWO ONE + ONE \n" +
"# else\n" +
"# undef TWO\n" +
"# define TWO 2 \n" +
"# endif\n" +
"#endif\n"); //$NON-NLS-1$" +
scanner.addDefinition("ONE", "one"); //$NON-NLS-1$ //$NON-NLS-2$
validateEOF();
validateBalance();

View file

@ -153,7 +153,8 @@ public class Scanner2 implements IScanner, IScannerData {
* @see org.eclipse.cdt.core.parser.IScanner#addDefinition(java.lang.String, java.lang.String)
*/
public void addDefinition(String key, String value) {
definitions.put(key.toCharArray(), value.toCharArray());
char[] ckey = key.toCharArray();
definitions.put(ckey, new ObjectStyleMacro(ckey, value.toCharArray()));
}
/* (non-Javadoc)
@ -249,7 +250,7 @@ public class Scanner2 implements IScanner, IScannerData {
}
// Return null to signify end of file
private IToken fetchToken() {
private IToken fetchToken() throws ScannerException {
contextLoop:
while (bufferStackPos >= 0) {
@ -853,10 +854,7 @@ public class Scanner2 implements IScanner, IScannerData {
new String(buffer, start, bufferPos[bufferStackPos] - start + 1));
}
private static char[] _define = "define".toCharArray();
private void handlePPDirective() {
private void handlePPDirective() throws ScannerException {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
@ -869,16 +867,27 @@ public class Scanner2 implements IScanner, IScannerData {
if (pos >= limit || buffer[pos] == '\n')
return;
// 'define'
if (pos + 5 < limit && CharArrayUtils.equals(buffer, pos, 6, _define)) {
if (isDefine()) {
bufferPos[bufferStackPos] += 5;
handlePPDefine();
return;
} else if (isIfdef()) {
bufferPos[bufferStackPos] += 4;
handlePPIfdef(true);
} else if (isIfndef()) {
bufferPos[bufferStackPos] += 5;
handlePPIfdef(false);
} else if (isElse() || isElif()) {
// Condition must have been true, skip over the rest
skipToNewLine();
skipOverConditionalCode(false);
} else if (isError()) {
throw new ScannerException(null);
} else {
// don't know, chew up to the end of line
// includes endif which is immatereal at this point
skipToNewLine();
}
// don't know, chew up to the end of line and return
while (++bufferPos[bufferStackPos] < limit && buffer[bufferPos[bufferStackPos]] != '\n')
;
}
private void handlePPDefine() {
@ -974,6 +983,89 @@ public class Scanner2 implements IScanner, IScannerData {
: new FunctionStyleMacro(name, text, arglist));
}
private void handlePPIfdef(boolean positive) {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
skipOverWhiteSpace();
// get the Identifier
int idstart = ++bufferPos[bufferStackPos];
if (idstart >= limit)
return;
char c = buffer[idstart];
if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_')) {
skipToNewLine();
return;
}
int idlen = 1;
while (++bufferPos[bufferStackPos] < limit) {
c = buffer[bufferPos[bufferStackPos]];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
|| c == '_' || (c >= '0' && c <= '9')) {
++idlen;
continue;
} else {
break;
}
}
--bufferPos[bufferStackPos];
skipToNewLine();
if ((definitions.get(buffer, idstart, idlen) != null) == positive)
// continue on
return;
// skip over this group
skipOverConditionalCode(true);
}
// checkelse - if potential for more, otherwise skip to endif
private void skipOverConditionalCode(boolean checkelse) {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
int nesting = 0;
while (bufferPos[bufferStackPos] < limit) {
skipOverWhiteSpace();
char c = buffer[++bufferPos[bufferStackPos]];
if (c == '#') {
skipOverWhiteSpace();
++bufferPos[bufferStackPos];
// TODO handle elif
if (isIfdef() || isIfndef()) {
++nesting;
skipToNewLine();
continue;
} else if (isElse()) {
if (checkelse && nesting == 0) {
skipToNewLine();
return;
} else {
skipToNewLine();
continue;
}
} else if (isEndif()) {
if (nesting > 0) {
--nesting;
skipToNewLine();
continue;
} else {
skipToNewLine();
return;
}
}
}
skipToNewLine();
}
}
private void skipOverWhiteSpace() {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
@ -1227,6 +1319,62 @@ public class Scanner2 implements IScanner, IScannerData {
pushContext(expText, exp);
}
private static final char[] _define = "define".toCharArray();
private boolean isDefine() {
char[] buffer = bufferStack[bufferStackPos];
int pos = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
return pos + 5 < limit && CharArrayUtils.equals(buffer, pos, 6, _define);
}
private static final char[] _ifdef = "ifdef".toCharArray();
private boolean isIfdef() {
char[] buffer = bufferStack[bufferStackPos];
int pos = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
return pos + 4 < limit && CharArrayUtils.equals(buffer, pos, 5, _ifdef);
}
private static final char[] _ifndef = "ifndef".toCharArray();
private boolean isIfndef() {
char[] buffer = bufferStack[bufferStackPos];
int pos = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
return pos + 5 < limit && CharArrayUtils.equals(buffer, pos, 6, _ifndef);
}
private static final char[] _elif = "elif".toCharArray();
private boolean isElif() {
char[] buffer = bufferStack[bufferStackPos];
int pos = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
return pos + 3 < limit && CharArrayUtils.equals(buffer, pos, 4, _elif);
}
private static final char[] _else = "else".toCharArray();
private boolean isElse() {
char[] buffer = bufferStack[bufferStackPos];
int pos = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
return pos + 3 < limit && CharArrayUtils.equals(buffer, pos, 4, _else);
}
private static final char[] _endif = "endif".toCharArray();
private boolean isEndif() {
char[] buffer = bufferStack[bufferStackPos];
int pos = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
return pos + 4 < limit && CharArrayUtils.equals(buffer, pos, 5, _endif);
}
private static final char[] _error = "error".toCharArray();
private boolean isError() {
char[] buffer = bufferStack[bufferStackPos];
int pos = bufferPos[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
return pos + 4 < limit && CharArrayUtils.equals(buffer, pos, 5, _error);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScanner#nextToken(boolean)
*/