Commit 6768c93b authored by Sebastian Pretscher's avatar Sebastian Pretscher

Merge branch 'master' of git@github.com:jroith/cup-eclipse.git

Conflicts:
	CupPlugin/src/de/tum/in/www2/cupplugin/model/CupParserASTChangeObserver.java
parents 555e511f 70ab400c
......@@ -14,7 +14,7 @@
<target name="generate">
<jflex file="${jflex}/Lexer.jflex" destdir="${java}" />
<cup srcfile="${cup}/Parser.cup" destdir="${java}"
parser="Parser" interface="true" locations="false" />
parser="Parser" interface="true" locations="true" />
</target>
<path id="libraries"> <files includes="${lib}/java-cup-11b-runtime.jar" /> </path>
......@@ -31,6 +31,10 @@
<manifest>
</manifest>
</jar>
<echo>Deploy in </echo>
<copy todir="../CupReferencedLibraries/" overwrite="true">
<fileset dir="${result}/" includes="*.jar"/>
</copy>
</target>
<target name="clean">
......
This diff is collapsed.
......@@ -20,8 +20,7 @@ public class CupContext
{
String name = cls.getName();
if (!singletons.containsKey(name)) {
System.out.println("setting up singleton for " + name + "!");
//System.out.println("setting up singleton for " + name + "!");
singletons.put(name, null); // just in case to prevent loops.
try {
Constructor<T> c = cls.getConstructor(
......@@ -48,17 +47,17 @@ public class CupContext
// TODO: this stuff is only needed for the emitter and can be easily removed!
// -> could also be extracted from the AST.
public static Stack<String> import_list = new Stack<String>();
public static String parser_class_name;
public static String package_name;
public static String action_code;
public static String parser_code;
public static String init_code;
public static String scan_code;
public static String symbol_const_class_name;
public Stack<String> import_list = new Stack<String>();
public String parser_class_name;
public String package_name;
public String action_code;
public String parser_code;
public String init_code;
public String scan_code;
public String symbol_const_class_name;
public static int num_conflicts;
public static production start_production;
public int num_conflicts;
public production start_production;
public Boolean getShowWarnings() {
return showWarnings;
......
......@@ -2,6 +2,7 @@
package de.in.tum.www2.cup;
import java.io.FileInputStream;
import java.io.InputStream;
import de.in.tum.www2.cup.ast.*;
import de.in.tum.www2.cup.internal.Parser;
......@@ -21,7 +22,7 @@ public class CupParser
return context;
}
public CupParser(IErrorReporter er, FileInputStream inputStream) {
public CupParser(IErrorReporter er, InputStream inputStream) {
context = new CupContext(er);
parser = new Parser();
parser.init(context.getErrorManager(), context, inputStream);
......@@ -33,6 +34,9 @@ public class CupParser
try {
parser.parse();
} catch (ParserAbortException e) {
System.out.println("PARSER ABORT!");
this.context = null;
return null;
}
......
......@@ -4,9 +4,10 @@ package de.in.tum.www2.cup;
import java.io.Reader;
import java.io.IOException;
import java.io.InputStream;
import de.in.tum.www2.cup.ErrorManager;
import java_cup.runtime.ComplexSymbolFactory;
import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
import de.in.tum.www2.cup.internal.Lexer;
public class CupScanner
......@@ -25,8 +26,9 @@ public class CupScanner
this.lexer = new Lexer(errMan, factory, r);
}
public java_cup.runtime.Symbol next_token() throws IOException {
return lexer.next_token();
public CupSymbol next_token() throws IOException {
ComplexSymbol symbol = (ComplexSymbol) lexer.next_token();
return new CupSymbol(symbol);
}
}
......
package de.in.tum.www2.cup;
import java.util.HashSet;
import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
import de.in.tum.www2.cup.internal.sym;
/**
* Wrapper class around symbols, so we can have a nice API.
*/
public class CupSymbol {
private ComplexSymbol cs;
public Object getValue() {
if (cs == null)
return null;
return cs.value;
}
public int getSymbolId() {
if (cs == null)
return -1;
return cs.sym;
}
// TODO: why not take this from xleft?
public int getLeft() {
if (cs == null)
return -1;
return cs.left;
}
// TODO: why not take this from xright?
public int getRight() {
if (cs == null)
return -1;
return cs.right;
}
// TODO: naming
public Position getXLeft() {
if (cs == null)
return null;
return Position.fromComplexSymbolLeft(cs);
}
// TODO: naming
public Position getXRight() {
if (cs == null)
return null;
return Position.fromComplexSymbolRight(cs);
}
CupSymbol(ComplexSymbol cs) {
this.cs = cs;
}
public boolean isTerminal (Declarations decls) {
if (decls == null || cs == null || cs.value == null || !(cs.value instanceof String))
return false;
return cs.sym == sym.ID && decls.isDeclaredTerminal((String) cs.value);
}
public boolean isNonTerminal (Declarations decls) {
if (decls == null || cs == null || cs.value == null || !(cs.value instanceof String))
return false;
return cs.sym == sym.ID && decls.isDeclaredNonTerminal((String) cs.value);
}
/**
* Note: this indicates that we found the special error terminal, which is
* used by the parser to indicate error handling.
* @return
*/
public boolean isSpecialErrorTerminal() {
return getValue() != null && getValue().equals("error");
}
public boolean isEOF() {
return getSymbolId() == sym.EOF;
}
public boolean isKeyword() {
if (cs == null)
return false;
return keywordSet.contains(cs.sym);
}
/***
*
* static methods
*
**/
private static HashSet<Integer> keywordSet;
private static int[] keywords;
private static String[] keywordStrings;
static {
keywords = new int[] {
sym.IMPORT,
sym.PARSER,
sym.WITH,
sym.SCAN,
sym.LEFT,
sym.RIGHT,
sym.PACKAGE,
sym.TERMINAL,
sym.NONTERMINAL,
sym.NON,
sym.PRECEDENCE,
sym.INIT,
sym.CODE,
sym.EXTENDS
};
keywordStrings = new String[keywords.length];
keywordSet = new HashSet<Integer>();
for (int i=0; i < keywords.length; i++) {
keywordSet.add(keywords[i]);
keywordStrings[i] = sym.terminalNames[keywords[i]];
}
}
public static String[] getKeywords() {
return keywordStrings;
}
}
package de.in.tum.www2.cup;
import java.util.HashSet;
public class Declarations {
private HashSet<String> terminals = new HashSet<String>();
private HashSet<String> non_terminals = new HashSet<String>();
public HashSet<String> getTerminals() {
return terminals;
}
public HashSet<String> getNonTerminals() {
return non_terminals;
}
public boolean isDeclaredTerminal(String name) {
return terminals.contains(name);
}
public boolean isDeclaredNonTerminal(String name) {
return non_terminals.contains(name);
}
public boolean isDeclared(String name) {
return isDeclaredTerminal(name) || isDeclaredNonTerminal (name);
}
@Override
public boolean equals(Object other) {
if (other == null)
return false;
if (other == this)
return true;
if (this.getClass().equals(other.getClass())) {
Declarations o = (Declarations) other;
return terminals.equals(o.terminals) &&
non_terminals.equals(o.non_terminals);
}
return false;
}
}
......@@ -3,17 +3,37 @@ package de.in.tum.www2.cup;
public class DefaultErrorReporter implements IErrorReporter
{
public void Warning(String msg) {
System.out.println("HELLO WARNING: " + msg);
}
public void Fatal(String msg) {
System.out.println("HELLO FATAL: " + msg);
}
public void Error(String msg) {
System.out.println("HELLO ERROR: " + msg);
public void report(ErrorType type, ErrorSource source, int errorCode,
String message, Position start, Position end)
{
StringBuilder m = new StringBuilder();
switch (type) {
case Info: m.append("CupParser Info [ "); break;
case Error: m.append("CupParser Error [ "); break;
case Fatal: m.append("CupParser Fatal [ "); break;
case Warning: m.append("CupParser Warning [ "); break;
}
m.append("code: ");
m.append(errorCode);
m.append(", source: ");
m.append(source);
if (start != null) {
m.append(", from: ");
m.append(start);
}
if (end != null) {
m.append(", to: ");
m.append(start);
}
if (message != null) {
m.append (", '");
m.append(message);
m.append ("'");
}
m.append(" ]");
System.out.println(m.toString());
}
}
......
......@@ -6,6 +6,7 @@ import java.util.Enumeration;
import java_cup.runtime.*;
import de.in.tum.www2.cup.*;
import de.in.tum.www2.cup.analysis.DeclarationsExtractorVisitor;
import de.in.tum.www2.cup.analysis.LocationPatchVisitor;
import de.in.tum.www2.cup.ast.*;
import de.in.tum.www2.cup.internal.emit;
......@@ -13,7 +14,6 @@ import de.in.tum.www2.cup.internal.emit;
class Demo
{
public static void main(String[] blah) throws Exception {
IErrorReporter er = new DefaultErrorReporter();
FileInputStream input = new FileInputStream("/Users/jroith/testcup/test.cup");
......@@ -23,15 +23,34 @@ class Demo
System.out.println(res);
System.out.println("LocationPatchVisitor:");
LocationPatchVisitor visitor = new LocationPatchVisitor();
res.accept(visitor, null);
System.out.println("\nLocationPatchVisitor:");
long ms = System.currentTimeMillis();
LocationPatchVisitor locVisitor = new LocationPatchVisitor(new Position(0,0,0), 0, 0);
res.accept(locVisitor, null);
System.out.println("millis: " + (System.currentTimeMillis() - ms));
System.out.println("Computing tables ...");
System.out.println("\nDeclarationVisitor:");
Declarations oldDecl = null;
DeclarationsExtractorVisitor declVisitor = new DeclarationsExtractorVisitor();
res.accept(declVisitor, null);
Declarations newDecl = declVisitor.getResult();
if (!newDecl.equals(oldDecl)) {
System.out.println("Declarations have changed. -> rescan whole document.");
}
if (!newDecl.isDeclared ("BLAH"))
System.out.println("BLAH is not a declared keyword! :-(");
if (!newDecl.isDeclaredTerminal("QUESTION"))
System.out.println("QUESTION is a declared terminal! :-)");
System.out.println("\nComputing tables ...");
LALRResult lalrResult = LALRResult.Compute(context, context.start_production);
System.out.println(lalrResult.action_table);
System.out.println(lalrResult.reduce_table);
// System.out.println(lalrResult.getActionTable());
// System.out.println(lalrResult.getReduceTable());
/*lalr_state ordered[] = new lalr_state[lalr_state.number()];
for (Enumeration s = lalr_state.all(); s.hasMoreElements(); )
......
......@@ -2,6 +2,7 @@
package de.in.tum.www2.cup;
import java_cup.runtime.*;
import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
public class ErrorManager
{
......@@ -16,28 +17,72 @@ public class ErrorManager
this.er = er;
}
public void Warning(String msg, Symbol sym) {
Warning (msg + "," + sym);
public void Warning(ErrorSource source, String msg, ComplexSymbol sym) {
Position start = null;
Position end = null;
if (sym != null) {
start = Position.fromComplexSymbolLeft(sym);
end = Position.fromComplexSymbolRight(sym);
}
Warning (source, msg + " - " + sym, start, end);
}
// public void Warning(String msg, Symbol sym) {
// Warning (msg + "," + sym);
// }
public void Warning(String msg) {
er.Warning(msg);
er.report(ErrorType.Warning, ErrorSource.Unknown, -1, msg, null, null);
}
public void Warning(ErrorSource source, String msg) {
Warning(source, msg, null, null);
}
public void Fatal(String msg, Symbol sym) {
Fatal (msg + "," + sym);
public void Warning(ErrorSource source, String msg, Position start) {
Warning(source, msg, start, null);
}
public void Fatal(String msg) {
er.Fatal(msg);
public void Warning(ErrorSource source, String msg, Position start, Position end) {
er.report(ErrorType.Warning, source, -1, msg, start, end);
}
public void Fatal(ErrorSource source, String msg, ComplexSymbol sym) {
Fatal (source, msg + "," + sym);
}
public void Fatal(ErrorSource source, String msg) {
er.report(ErrorType.Fatal, source, -1, msg, null, null);
}
public void Error(ErrorSource source, String msg, ComplexSymbol sym) {
Position start = null;
Position end = null;
if (sym != null) {
start = Position.fromComplexSymbolLeft(sym);
end = Position.fromComplexSymbolRight(sym);
}
Error (source, msg + " - " + sym, start, end);
}
public void Error(String msg, Symbol sym) {
Error (msg + "," + sym);
Error (msg + ", " + sym);
}
public void Error(String msg) {
er.Error(msg);
Error(ErrorSource.Unknown, msg, null, null);
}
public void Error(ErrorSource source, String msg, Position start) {
Error(source, msg, start, null);
}
public void Error(ErrorSource source, String msg, Position start, Position end) {
er.report(ErrorType.Error, source, -1, msg, start, end);
error_count++;
}
}
......
package de.in.tum.www2.cup;
public enum ErrorSource {
Unknown,
Scanner,
Parser,
LALR,
Analyzer
}
package de.in.tum.www2.cup;
public enum ErrorType {
Info,
Error,
Warning,
Fatal
}
......@@ -3,8 +3,17 @@ package de.in.tum.www2.cup;
public interface IErrorReporter
{
void Warning(String msg);
void Fatal(String msg);
void Error(String msg);
/**
*
* @param type
* @param source
* @param errorCode May be -1 if no code is known.
* @param message May be null if no message is provided.
* @param start May be null if there is no line information.
* @param end May be null if the error is not localized on the line.
*/
void report(ErrorType type, ErrorSource source, int errorCode,
String message, Position start, Position end);
}
package de.in.tum.www2.cup;
import java.util.Enumeration;
import de.in.tum.www2.cup.internal.emit;
import de.in.tum.www2.cup.internal.internal_error;
import de.in.tum.www2.cup.internal.lalr_state;
import de.in.tum.www2.cup.internal.non_terminal;
......@@ -12,9 +10,21 @@ import de.in.tum.www2.cup.internal.production;
public class LALRResult {
public lalr_state start_state;
public parse_action_table action_table;
public parse_reduce_table reduce_table;
private lalr_state start_state;
private parse_action_table action_table;
private parse_reduce_table reduce_table;
public lalr_state getStartState() {
return start_state;
}
public parse_action_table getActionTable() {
return action_table;
}
public parse_reduce_table getReduceTable() {
return reduce_table;
}
private LALRResult() {
}
......@@ -45,8 +55,8 @@ public class LALRResult {
{
System.out.println("*** More conflicts encountered than expected " +
"-- parser generation aborted");
// indicate the problem.
// we'll die on return, after clean up.
return null;
}
return result;
......
package de.in.tum.www2.cup;
import java.util.List;
public class MultiErrorReporter implements IErrorReporter
{
List<IErrorReporter> reporters;
public MultiErrorReporter (List<IErrorReporter> reporters) {
this.reporters = reporters;
}
public void report(ErrorType type, ErrorSource source, int errorCode,
String message, Position start, Position end)
{
for (IErrorReporter reporter : reporters)
reporter.report(type, source, errorCode, message, start, end);
}
}
package de.in.tum.www2.cup;
public class NoopErrorReporter implements IErrorReporter
{
public void report(ErrorType type, ErrorSource source, int errorCode,
String message, Position start, Position end)
{
}
}
package de.in.tum.www2.cup;
import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
import java_cup.runtime.ComplexSymbolFactory.Location;
public class Position {
private int line;
private int column;
private int offsetFromStart;
public int getLine() { return line; }
public int getColumn() { return column; }
public int getOffsetFromStart() { return offsetFromStart; }
public Position(int line, int column, int offsetFromStart) {
this.line = line;
this.column = column;
this.offsetFromStart = offsetFromStart;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(line);
builder.append("/");
builder.append(column);
return builder.toString();
}
public String toLongString() {
StringBuilder builder = new StringBuilder();
builder.append("line ");
builder.append(line);
builder.append(", at ");
builder.append(column);
return builder.toString();
}
public static Position fromLocation(Location loc) {
return new Position(loc.getLine(),
loc.getColumn(),
loc.getOffset());
}
// TODO: temporary hack for parser. Remove later!
public static Position fromComplexSymbolLeft(ComplexSymbol symbol) {
return new Position(symbol.xleft.getLine(),
symbol.xleft.getColumn(),
symbol