aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/anarres/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/anarres/cpp')
-rw-r--r--src/java/org/anarres/cpp/Macro.java39
-rw-r--r--src/java/org/anarres/cpp/Preprocessor.java90
-rw-r--r--src/java/org/anarres/cpp/Source.java4
3 files changed, 112 insertions, 21 deletions
diff --git a/src/java/org/anarres/cpp/Macro.java b/src/java/org/anarres/cpp/Macro.java
index 0d0ae55..51e9ecd 100644
--- a/src/java/org/anarres/cpp/Macro.java
+++ b/src/java/org/anarres/cpp/Macro.java
@@ -118,6 +118,27 @@ public class Macro {
return tokens;
}
+ public String getText() {
+ StringBuilder buf = new StringBuilder();
+ boolean paste = false;
+ for (int i = 0; i < tokens.size(); i++) {
+ Token tok = tokens.get(i);
+ if (tok.getType() == Token.M_PASTE) {
+ paste = true;
+ continue;
+ }
+ else {
+ buf.append(tok.getText());
+ }
+ if (paste) {
+ buf.append(" #" + "# ");
+ paste = false;
+ }
+ // buf.append(tokens.get(i));
+ }
+ return buf.toString();
+ }
+
public String toString() {
StringBuilder buf = new StringBuilder(name);
if (args != null) {
@@ -133,23 +154,7 @@ public class Macro {
buf.append(')');
}
if (!tokens.isEmpty()) {
- boolean paste = false;
- buf.append(" => ");
- for (int i = 0; i < tokens.size(); i++) {
- Token tok = tokens.get(i);
- if (tok.getType() == Token.M_PASTE) {
- paste = true;
- continue;
- }
- else {
- buf.append(tok.getText());
- }
- if (paste) {
- buf.append(" #" + "# ");
- paste = false;
- }
- // buf.append(tokens.get(i));
- }
+ buf.append(" => ").append(getText());
}
return buf.toString();
}
diff --git a/src/java/org/anarres/cpp/Preprocessor.java b/src/java/org/anarres/cpp/Preprocessor.java
index c1b87d7..5d4b6d4 100644
--- a/src/java/org/anarres/cpp/Preprocessor.java
+++ b/src/java/org/anarres/cpp/Preprocessor.java
@@ -112,6 +112,8 @@ public class Preprocessor {
listener.handleError(source,
tok.getLine(), tok.getColumn(),
msg);
+ else
+ throw new LexerException("Error at " + tok.getLine() + ":" + tok.getColumn() + ": " + msg);
}
/**
@@ -123,9 +125,11 @@ public class Preprocessor {
protected void warning(Token tok, String msg)
throws LexerException {
if (listener != null)
- listener.handleError(source,
+ listener.handleWarning(source,
tok.getLine(), tok.getColumn(),
msg);
+ else
+ throw new LexerException("Warning at " + tok.getLine() + ":" + tok.getColumn() + ": " + msg);
}
/*
@@ -191,6 +195,9 @@ public class Preprocessor {
return macros;
}
+ public Macro getMacro(String name) {
+ return macros.get(name);
+ }
/* States */
@@ -255,6 +262,13 @@ public class Preprocessor {
listener.handleSourceChange(this.source, "pop");
}
+ /**
+ * Pushes a source into the input stack.
+ */
+ public void addSource(Source source) {
+ push_source(source, true);
+ }
+
/* Source tokens */
@@ -311,6 +325,7 @@ public class Preprocessor {
LexerException {
Token tok;
do {
+ /* XXX This _should_ never be a NL token, I think. */
tok = source_token();
} while (isWhite(tok));
return tok;
@@ -830,6 +845,74 @@ public class Preprocessor {
}
}
+ protected void pragma(Token name, List<Token> value)
+ throws IOException,
+ LexerException {
+ warning(name, "Unknown #" + "pragma: " + name.getText());
+ }
+
+ private Token pragma()
+ throws IOException,
+ LexerException {
+ Token name;
+
+ NAME: for (;;) {
+ Token tok = token();
+ switch (tok.getType()) {
+ case EOF:
+ /* There ought to be a newline before EOF.
+ * At least, in any skipline context. */
+ /* XXX Are we sure about this? */
+ warning(tok,
+ "End of file in #" + "pragma");
+ return tok;
+ case NL:
+ /* This may contain one or more newlines. */
+ warning(tok,
+ "Empty #" + "pragma");
+ return tok;
+ case COMMENT:
+ case WHITESPACE:
+ continue NAME;
+ case IDENTIFIER:
+ name = tok;
+ break NAME;
+ default:
+ return source_skipline(false);
+ }
+ }
+
+ Token tok;
+ List<Token> value = new ArrayList<Token>();
+ VALUE: for (;;) {
+ tok = token();
+ switch (tok.getType()) {
+ case EOF:
+ /* There ought to be a newline before EOF.
+ * At least, in any skipline context. */
+ /* XXX Are we sure about this? */
+ warning(tok,
+ "End of file in #" + "pragma");
+ break VALUE;
+ case NL:
+ /* This may contain one or more newlines. */
+ break VALUE;
+ case COMMENT:
+ break;
+ case WHITESPACE:
+ value.add(tok);
+ break;
+ default:
+ value.add(tok);
+ break;
+ }
+ }
+
+ pragma(name, value);
+
+ return tok; /* The NL. */
+ }
+
/* For #error and #warning. */
private void error(Token pptok, boolean is_error)
throws IOException,
@@ -1420,7 +1503,10 @@ public class Preprocessor {
// break;
case PP_PRAGMA:
- return source_skipline(false);
+ if (!isActive())
+ return source_skipline(false);
+ else
+ return pragma();
// break;
default:
diff --git a/src/java/org/anarres/cpp/Source.java b/src/java/org/anarres/cpp/Source.java
index 2999418..7b269b6 100644
--- a/src/java/org/anarres/cpp/Source.java
+++ b/src/java/org/anarres/cpp/Source.java
@@ -212,7 +212,7 @@ public abstract class Source implements Iterable<Token> {
if (listener != null)
listener.handleError(this, line, column, msg);
else
- throw new LexerException("No handler for error at " + line + ":" + column + ": " + msg);
+ throw new LexerException("Error at " + line + ":" + column + ": " + msg);
}
protected void warning(int line, int column, String msg)
@@ -220,7 +220,7 @@ public abstract class Source implements Iterable<Token> {
if (listener != null)
listener.handleWarning(this, line, column, msg);
else
- throw new LexerException("No handler for warning at " + line + ":" + column + ": " + msg);
+ throw new LexerException("Warning at " + line + ":" + column + ": " + msg);
}
}