diff options
Diffstat (limited to 'src/java/org/anarres')
-rw-r--r-- | src/java/org/anarres/cpp/Macro.java | 39 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Preprocessor.java | 90 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Source.java | 4 |
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); } } |