Commit f5dde6b8 authored by Johannes Roith's avatar Johannes Roith

Basic statistics.

parent c11ab2f6
......@@ -19,7 +19,6 @@ public class ConflictManager
}
public void addConflict(Conflict conflict) {
System.out.println("DEBUG: ADDING CONFLICT TO " + this + "!"); // TODO: remove
this.conflicts.add(conflict);
}
}
......
......@@ -16,6 +16,7 @@ public class CupContext
private ErrorManager errorManager;
private ConflictManager conflictManager;
private Statistics statistics;
private HashMap<String, Object> singletons = new HashMap<String, Object>();
public <T> T getForContext(Class<T> cls)
......@@ -85,8 +86,13 @@ public class CupContext
return conflictManager;
}
public Statistics getStatistics() {
return statistics;
}
public CupContext (IErrorReporter er) {
this.errorManager = new ErrorManager(er);
this.statistics = new Statistics();
this.errorManager = new ErrorManager(er, statistics);
this.conflictManager = new ConflictManager(this);
}
......
......@@ -16,13 +16,13 @@ public class CupScanner
public CupScanner(IErrorReporter er, InputStream is) {
ComplexSymbolFactory factory = new ComplexSymbolFactory();
ErrorManager errMan = new ErrorManager(er);
ErrorManager errMan = new ErrorManager(er, null);
this.lexer = new Lexer(errMan, factory, is);
}
public CupScanner(IErrorReporter er, Reader r) {
ComplexSymbolFactory factory = new ComplexSymbolFactory();
ErrorManager errMan = new ErrorManager(er);
ErrorManager errMan = new ErrorManager(er, null);
this.lexer = new Lexer(errMan, factory, r);
}
......
......@@ -6,6 +6,7 @@ import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
public class ErrorManager
{
private Statistics statistics;
private IErrorReporter er;
private int error_count;
private int parser_error_count;
......@@ -36,8 +37,9 @@ public class ErrorManager
return error_count;
}
public ErrorManager (IErrorReporter er) {
public ErrorManager (IErrorReporter er, Statistics statistics) {
this.er = er;
this.statistics = statistics;
}
public void Warning(ErrorSource source, String msg, ComplexSymbol sym) {
......@@ -111,6 +113,8 @@ public class ErrorManager
public void Error(ErrorSource source, String msg, Position start, Position end) {
er.report(ErrorType.Error, source, null, msg, start, end);
error_count++;
if (statistics != null)
statistics.incrementErrorCount();
switch (source) {
case Parser: parser_error_count++; break;
case Scanner: scanner_error_count++; break;
......
package de.in.tum.www2.cup;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import de.in.tum.www2.cup.internal.*;
public class Statistics
{
private int error_count;
private int parser_error_count;
private int scanner_error_count;
private int lalr_error_count;
public int getErrorCount() {
return error_count;
}
public int getParserErrorCount() {
return parser_error_count;
}
public int getScannerErrorCount() {
return scanner_error_count;
}
public int getLalrErrorCount() {
return lalr_error_count;
}
void incrementErrorCount() {
error_count += 1;
}
}
......@@ -31,7 +31,7 @@ import de.tum.in.www2.cupplugin.model.Model;
public class DocumentDidChangeJob extends Job {
boolean iAmCurrentlyRunning = false;
CupTextEditor myEditor = null;
CupTextEditor editor = null;
private List<DocumentEvent> documentEvents;
private EnumSet<JobsToDo> jobs;
......@@ -47,7 +47,7 @@ public class DocumentDidChangeJob extends Job {
public DocumentDidChangeJob(CupTextEditor editor) {
super("" + editor.hashCode());
myEditor = editor;
this.editor = editor;
jobStatusList = new ArrayList<JobStatus>();
}
......@@ -87,20 +87,20 @@ public class DocumentDidChangeJob extends Job {
// We need these null checks, because the document might have been
// closed already.
if (myEditor == null)
if (editor == null)
return Status.CANCEL_STATUS;
IDocumentProvider provider = myEditor.getDocumentProvider();
IDocumentProvider provider = editor.getDocumentProvider();
if (provider == null)
return Status.CANCEL_STATUS;
IDocument document = provider.getDocument(myEditor.getEditorInput());
IDocument document = provider.getDocument(editor.getEditorInput());
if (document == null)
return Status.CANCEL_STATUS;
IFile file = ((FileEditorInput) myEditor.getEditorInput()).getFile();
IFile file = ((FileEditorInput) editor.getEditorInput()).getFile();
CupEditorErrorReporter errorReporter = new CupEditorErrorReporter(file);
errorReporter.resetOnNextPush();
......@@ -162,7 +162,7 @@ public class DocumentDidChangeJob extends Job {
if (lalrResult != null) {
jobStatusList.add(new JobStatus(JobsToDo.buildTable, false));
LaLrResultJob resultLaLrModelJob = new LaLrResultJob(myEditor,
LaLrResultJob resultLaLrModelJob = new LaLrResultJob(editor,
lalrResult, revNumber, context);
resultLaLrModelJob.setSystem(true);
resultLaLrModelJob.schedule();
......@@ -187,7 +187,7 @@ public class DocumentDidChangeJob extends Job {
jobs.clear();
iAmCurrentlyRunning = false;
CallbackJob cb = new CallbackJob(myEditor, jobStatusList);
CallbackJob cb = new CallbackJob(editor, jobStatusList);
cb.setSystem(true);
cb.schedule();
......@@ -231,16 +231,12 @@ public class DocumentDidChangeJob extends Job {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
IDocumentProvider provider = myEditor.getDocumentProvider();
if (provider != null) {
IDocument document = provider.getDocument(myEditor
.getEditorInput());
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setASTModel(this.parserResult, context, revNumber);
return Status.OK_STATUS;
}
IDocument document = editor.getDocument();
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setASTModel(this.parserResult, context, revNumber);
model.setStatistics(context.getStatistics(), revNumber);
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
}
......@@ -258,7 +254,7 @@ public class DocumentDidChangeJob extends Job {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
Controller controller = Controller.getInstance(myEditor);
Controller controller = Controller.getInstance(editor);
if (documentDidChangeJob.documentEvents == null
|| documentDidChangeJob.documentEvents.isEmpty()) {
......@@ -275,10 +271,10 @@ public class DocumentDidChangeJob extends Job {
documentDidChangeJob.jobs.addAll(controller.popJobsToDo());
}
jobStatusList.clear();
if (myEditor == null)
if (editor == null)
return Status.CANCEL_STATUS;
IDocument document = myEditor.getDocument();
IDocument document = editor.getDocument();
if (revNumber != RevisionManager.get(document))
return Status.CANCEL_STATUS;
......
......@@ -14,7 +14,7 @@ import de.tum.in.www2.cupplugin.model.Model;
public class LaLrResultJob extends UIJob {
private LALRResult lalrResult;
private long lalrResulRevisionNumber;
private long lalrResultRevisionNumber;
private CupContext lalrContext;
private CupTextEditor editor;
......@@ -23,7 +23,7 @@ public class LaLrResultJob extends UIJob {
super("LaLr Result UI Job");
this.editor = editor;
this.lalrResult = result;
this.lalrResulRevisionNumber = revisionNumber;
this.lalrResultRevisionNumber = revisionNumber;
this.lalrContext = context;
}
......@@ -32,8 +32,9 @@ public class LaLrResultJob extends UIJob {
IDocument document = editor.getDocument();
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setLaLrResultModel(this.lalrResult, lalrResulRevisionNumber,
model.setLaLrResultModel(this.lalrResult, lalrResultRevisionNumber,
lalrContext);
model.setStatistics(lalrContext.getStatistics(), lalrResultRevisionNumber);
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
......
......@@ -8,6 +8,7 @@ import org.eclipse.jface.text.IDocument;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.LALRResult;
import de.in.tum.www2.cup.Statistics;
import de.in.tum.www2.cup.ast.ParserResult;
public class Model {
......@@ -21,7 +22,10 @@ public class Model {
private LALRResult lalrModel;
private long lalrModelRevisionNumber;
private CupContext lalrContext;
private Statistics statistics;
private final Object statisticsLock = new Object();
private final Object parserModelLock = new Object();
private final Object lalrModellock = new Object();
private List<Object> modelObservers;
......@@ -88,6 +92,18 @@ public class Model {
return astModel;
}
}
public Statistics getStatistics() {
synchronized(statisticsLock) {
return statistics;
}
}
public void setStatistics(Statistics statistics, long revisionNumber) {
synchronized(statisticsLock) {
this.statistics = statistics;
}
}
public void setASTModel(ParserResult result, CupContext context, long revisionNumber) {
synchronized (parserModelLock) {
......
package de.tum.in.www2.cupplugin.views;
import java.sql.Time;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.SWT;
......@@ -11,12 +12,15 @@ import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.cup.Statistics;
import de.in.tum.www2.cup.ast.ParserResult;
import de.tum.in.www2.cupplugin.Pair;
import de.tum.in.www2.cupplugin.controller.Controller.JobsToDo;
import de.tum.in.www2.cupplugin.controller.Controller;
import de.tum.in.www2.cupplugin.controller.IRegisterForControllerChanges;
......@@ -26,11 +30,45 @@ import de.tum.in.www2.cupplugin.editors.ICupEditorPageVisibility;
import de.tum.in.www2.cupplugin.editors.Jumper;
import de.tum.in.www2.cupplugin.model.ICupParserASTChangeObserver;
import de.tum.in.www2.cupplugin.model.ICupParserLaLrChangeObserver;
import de.tum.in.www2.cupplugin.model.ICupStatisticsChangeObserver;
import de.tum.in.www2.cupplugin.model.Model;
public class CupOverviewView extends FailableView implements IRegisterForControllerChanges,
ICupEditorPageVisibility, ICupParserLaLrChangeObserver,
ICupParserASTChangeObserver {
public class CupOverviewView extends FailableView
implements IRegisterForControllerChanges,
ICupEditorPageVisibility,
ICupParserLaLrChangeObserver,
ICupParserASTChangeObserver,
ICupStatisticsChangeObserver {
class SimpleTable {
private List<Label> labels;
private List<Label> values;
public void setRowValue(int index, int val) {
values.get(index).setText("" + val);
}
public void setRowValue(int index, String val) {
values.get(index).setText(val);
}
public void setRowLabel(int index, String val) {
labels.get(index).setText(val);
}
public SimpleTable() {
labels = new ArrayList<Label>();
values = new ArrayList<Label>();
}
public void addRow(Label label, Label val) {
labels.add(label);
values.add(val);
}
}
private static final int ERROR_ROW = 2;
private static final int OUTER_MARGIN = 10;
private static final int INNER_MARGIN = 10;
......@@ -48,39 +86,61 @@ public class CupOverviewView extends FailableView implements IRegisterForControl
private static final String SECTION_CONFLICTS = "Conflicts";
private static final String SECTION_CONFLICTS_DESCRIPTION_TEMPLATE = "Number of conflicts, etc.";
private Pair<Composite,SimpleTable> analysisSection;
boolean visible = false;
private IDocument doc;
private FormToolkit toolkit;
private ScrolledForm form;
private CupTextEditor myEditor;
HashSet<Composite> sections = new HashSet<Composite>();
private CupTextEditor editor;
public CupOverviewView(Composite realParent, Jumper jumper, IDocument doc,
String title, CupTextEditor editor) {
super(realParent);
Composite parent = getMain();
this.doc = doc;
setupForm(parent, title);
myEditor = editor;
this.editor = editor;
Controller.getInstance(editor).registerObserver(this);
Model.getInstanceForDocument(doc).registerModelObserver(this);
sections.add(createSection(SECTION_ANALYSIS,
SECTION_ANALYSIS_DESCRIPTION_TEMPLATE, false));
sections.add(createSection(SECTION_PARSE_TABLES,
SECTION_PARSE_TABLES_DESCRIPTION_TEMPLATE, false));
sections.add(createSection(SECTION_CONTENT,
SECTION_CONTENT_DESCRIPTION_TEMPLATE, true));
sections.add(createSection(SECTION_GRAMMAR,
SECTION_GRAMMAR_DESCRIPTION_TEMPLATE, false));
sections.add(createSection(SECTION_CONFLICTS,
SECTION_CONFLICTS_DESCRIPTION_TEMPLATE, false));
analysisSection = createTableSection(SECTION_ANALYSIS,
SECTION_ANALYSIS_DESCRIPTION_TEMPLATE, false, 10);
analysisSection.getSecond().setRowLabel(ERROR_ROW, "Errors:");
createSection(SECTION_PARSE_TABLES,
SECTION_PARSE_TABLES_DESCRIPTION_TEMPLATE, false);
createSection(SECTION_CONTENT,
SECTION_CONTENT_DESCRIPTION_TEMPLATE, true);
createSection(SECTION_GRAMMAR,
SECTION_GRAMMAR_DESCRIPTION_TEMPLATE, false);
createSection(SECTION_CONFLICTS,
SECTION_CONFLICTS_DESCRIPTION_TEMPLATE, false);
}
private Pair<Composite,SimpleTable> createTableSection(String title, String description, boolean doSpan, int rowCount) {
Composite section = createSection(title, description, doSpan);
SimpleTable tbl = new SimpleTable();
GridLayout gl = new GridLayout();
gl.numColumns = 2;
section.setLayout(gl);
for (int i=0; i < rowCount; i++) {
Label label = new Label(section, SWT.NONE);
label.setText("TODO");
Label val = new Label(section, SWT.NONE);
val.setText("TODO");
tbl.addRow(label, val);
}
return new Pair<Composite,SimpleTable>(section, tbl);
}
private Composite createSection(String title, String description,
boolean doSpan) {
Section section = toolkit.createSection(form.getBody(),
......@@ -103,7 +163,6 @@ public class CupOverviewView extends FailableView implements IRegisterForControl
client.setLayout(layout);
section.setClient(client);
return client;
}
private void setupForm(Composite parent, String title) {
......@@ -132,7 +191,7 @@ public class CupOverviewView extends FailableView implements IRegisterForControl
public void willBecomeVisible() {
System.out.println("CupOverviewView will become visible.");
visible = true;
if (!Controller.getInstance(myEditor).requestJobRun()) {
if (!Controller.getInstance(editor).requestJobRun()) {
// TODO: Handle no rerun!!
}
......@@ -149,66 +208,36 @@ public class CupOverviewView extends FailableView implements IRegisterForControl
@Override
public EnumSet<JobsToDo> getRequiredJobs() {
return visible ? EnumSet.of(JobsToDo.buildTable, JobsToDo.parseCode)
: EnumSet.noneOf(JobsToDo.class);
// we never request jobs ourselves.
return EnumSet.noneOf(JobsToDo.class);
}
@Override
public void jobStatusChanged(JobStatus status) {
// TODO Auto-generated method stub
}
private void updateStatistics(Statistics statistics) {
if (statistics == null)
return;
analysisSection.getSecond().setRowValue(ERROR_ROW, statistics.getErrorCount());
}
@Override
public void modelChanged(Model model) {
System.out.println("ModelChangedEvent");
if (model == null) {
if (model == null)
return;
}
updateStatistics(model.getStatistics());
ParserResult astModel = model.getAstModel();
if(astModel == null){
return;
}
ErrorManager eManager = model.getAstModelContext().getErrorManager();
for (Composite e : sections) {
Section section = (Section) e.getParent();
switch (section.getText()) {
case SECTION_ANALYSIS:
int redundantProductions = 0;
int unusedTerminals = 0;
int unusedNonTerminals = 0;
section.setDescription(String.format(SECTION_ANALYSIS_DESCRIPTION_TEMPLATE,redundantProductions,unusedTerminals,unusedNonTerminals));
break;
case SECTION_CONFLICTS:
section.setDescription(String.format(SECTION_CONFLICTS_DESCRIPTION_TEMPLATE));
break;
case SECTION_CONTENT:
section.setDescription(String.format(SECTION_CONTENT_DESCRIPTION_TEMPLATE));
break;
case SECTION_GRAMMAR:
section.setDescription(String.format(SECTION_GRAMMAR_DESCRIPTION_TEMPLATE));
break;
case SECTION_PARSE_TABLES:
section.setDescription(String.format(SECTION_PARSE_TABLES_DESCRIPTION_TEMPLATE));
break;
default:
break;
}
}
}
@Override
public void jobStatusChanged(JobStatus status) {
// TODO Auto-generated method stub
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment