You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.3 KiB
153 lines
4.3 KiB
5 years ago
|
package com.fr.third.antlr;
|
||
|
|
||
|
import java.io.OutputStream;
|
||
|
import java.io.PrintWriter;
|
||
|
import java.io.Writer;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.Collections;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Iterator;
|
||
|
import java.util.List;
|
||
|
import java.util.Map;
|
||
|
|
||
|
// assumes one source file for now -- may need to change if ANTLR allows
|
||
|
// file inclusion in the future
|
||
|
// TODO optimize the output using line ranges for input/output files
|
||
|
// currently this writes one mapping per line
|
||
|
public class PrintWriterWithSMAP extends PrintWriter {
|
||
|
private int currentOutputLine = 1;
|
||
|
private int currentSourceLine = 0;
|
||
|
private Map sourceMap = new HashMap();
|
||
|
|
||
|
private boolean lastPrintCharacterWasCR = false;
|
||
|
private boolean mapLines = false;
|
||
|
private boolean mapSingleSourceLine = false;
|
||
|
private boolean anythingWrittenSinceMapping = false;
|
||
|
|
||
|
public PrintWriterWithSMAP(OutputStream out) {
|
||
|
super(out);
|
||
|
}
|
||
|
public PrintWriterWithSMAP(OutputStream out, boolean autoFlush) {
|
||
|
super(out, autoFlush);
|
||
|
}
|
||
|
public PrintWriterWithSMAP(Writer out) {
|
||
|
super(out);
|
||
|
}
|
||
|
public PrintWriterWithSMAP(Writer out, boolean autoFlush) {
|
||
|
super(out, autoFlush);
|
||
|
}
|
||
|
|
||
|
public void startMapping(int sourceLine) {
|
||
|
mapLines = true;
|
||
|
if (sourceLine != JavaCodeGenerator.CONTINUE_LAST_MAPPING)
|
||
|
currentSourceLine = sourceLine;
|
||
|
}
|
||
|
|
||
|
public void startSingleSourceLineMapping(int sourceLine) {
|
||
|
mapSingleSourceLine = true;
|
||
|
mapLines = true;
|
||
|
if (sourceLine != JavaCodeGenerator.CONTINUE_LAST_MAPPING)
|
||
|
currentSourceLine = sourceLine;
|
||
|
}
|
||
|
|
||
|
public void endMapping() {
|
||
|
mapLine(false);
|
||
|
mapLines = false;
|
||
|
mapSingleSourceLine = false;
|
||
|
}
|
||
|
|
||
|
protected void mapLine(boolean incrementOutputLineCount) {
|
||
|
if (mapLines && anythingWrittenSinceMapping) {
|
||
|
Integer sourceLine = new Integer(currentSourceLine);
|
||
|
Integer outputLine = new Integer(currentOutputLine);
|
||
|
List outputLines = (List)sourceMap.get(sourceLine);
|
||
|
if (outputLines == null) {
|
||
|
outputLines = new ArrayList();
|
||
|
sourceMap.put(sourceLine,outputLines);
|
||
|
}
|
||
|
if (!outputLines.contains(outputLine))
|
||
|
outputLines.add(outputLine);
|
||
|
}
|
||
|
if (incrementOutputLineCount)
|
||
|
currentOutputLine++;
|
||
|
if (!mapSingleSourceLine)
|
||
|
currentSourceLine++;
|
||
|
anythingWrittenSinceMapping = false;
|
||
|
}
|
||
|
|
||
|
public void dump(PrintWriter smapWriter, String targetClassName, String grammarFile) {
|
||
|
smapWriter.println("SMAP");
|
||
|
smapWriter.println(targetClassName + ".java");
|
||
|
smapWriter.println('G');
|
||
|
smapWriter.println("*S G");
|
||
|
smapWriter.println("*F");
|
||
|
smapWriter.println("+ 0 " + grammarFile);
|
||
|
smapWriter.println(grammarFile);
|
||
|
smapWriter.println("*L");
|
||
|
List sortedSourceLines = new ArrayList(sourceMap.keySet());
|
||
|
Collections.sort(sortedSourceLines);
|
||
|
for (Iterator i = sortedSourceLines.iterator(); i.hasNext();) {
|
||
|
Integer sourceLine = (Integer)i.next();
|
||
|
List outputLines = (List)sourceMap.get(sourceLine);
|
||
|
for (Iterator j = outputLines.iterator(); j.hasNext();) {
|
||
|
Integer outputLine = (Integer)j.next();
|
||
|
smapWriter.println(sourceLine + ":" + outputLine);
|
||
|
}
|
||
|
}
|
||
|
smapWriter.println("*E");
|
||
|
smapWriter.close();
|
||
|
}
|
||
|
|
||
|
public void write(char[] buf, int off, int len) {
|
||
|
int stop = off+len;
|
||
|
for(int i = off; i < stop; i++) {
|
||
|
checkChar(buf[i]);
|
||
|
}
|
||
|
super.write(buf,off,len);
|
||
|
}
|
||
|
|
||
|
// after testing, may want to inline this
|
||
|
public void checkChar(int c) {
|
||
|
if (lastPrintCharacterWasCR && c != '\n')
|
||
|
mapLine(true);
|
||
|
|
||
|
else if (c == '\n')
|
||
|
mapLine(true);
|
||
|
|
||
|
else if (!Character.isWhitespace((char)c))
|
||
|
anythingWrittenSinceMapping = true;
|
||
|
|
||
|
lastPrintCharacterWasCR = (c == '\r');
|
||
|
}
|
||
|
public void write(int c) {
|
||
|
checkChar(c);
|
||
|
super.write(c);
|
||
|
}
|
||
|
public void write(String s, int off, int len) {
|
||
|
int stop = off+len;
|
||
|
for(int i = off; i < stop; i++) {
|
||
|
checkChar(s.charAt(i));
|
||
|
}
|
||
|
super.write(s,off,len);
|
||
|
}
|
||
|
|
||
|
// PrintWriter delegates write(char[]) to write(char[], int, int)
|
||
|
// PrintWriter delegates write(String) to write(String, int, int)
|
||
|
|
||
|
// dependent on current impl of PrintWriter, which directly
|
||
|
// dumps a newline sequence to the target file w/o going through
|
||
|
// the other write methods.
|
||
|
public void println() {
|
||
|
mapLine(true);
|
||
|
super.println();
|
||
|
lastPrintCharacterWasCR = false;
|
||
|
}
|
||
|
public Map getSourceMap() {
|
||
|
return sourceMap;
|
||
|
}
|
||
|
|
||
|
public int getCurrentOutputLine() {
|
||
|
return currentOutputLine;
|
||
|
}
|
||
|
}
|