Commit 6374c1d0 authored by Johannes Roith's avatar Johannes Roith

- Possible fix to outline bug.

- Link internal model to AST.
- Some more more on conflicts view.
parent 96575236
......@@ -711,7 +711,7 @@ start_spec ::=
add_rhs_part(new symbol_part(terminal_shared.getEOF()));
if (!context.getXmlActions()) add_rhs_part(new action_part("RESULT = start_val;"));
production p = new production(context, non_terminal_shared.getSTART_nt(), rhs_parts, rhs_pos);
production p = new production(context, null, non_terminal_shared.getSTART_nt(), rhs_parts, rhs_pos);
//p.index();
context.start_production = p;
new_rhs();
......@@ -794,6 +794,17 @@ rhs ::=
prod_part_list : ppl PERCENT_PREC term_id:term_name
{:
symbol sym = null;
Range range = Range.fromLocations(term_namexleft, term_namexright);
ProductionRight pr = new ProductionRight(
ast_get_rhs_parts_copy(),
new Terminal(
new Name(term_name, range),
(Range) range.clone()
),
Range.fromLocations(pplxleft, term_namexright));
if (lhs_nt != null)
{
/* Find the precedence symbol */
......@@ -816,29 +827,22 @@ rhs ::=
sym = sp.the_symbol();
}
/* build the production */
production p;
if ((sym!=null) && (sym instanceof terminal)) {
p = new production(context, lhs_nt, rhs_parts, rhs_pos,
p = new production(context, pr, lhs_nt, rhs_parts, rhs_pos,
((terminal)sym).precedence_num(),
((terminal)sym).precedence_side());
((symbol_part)symbols.get(term_name)).the_symbol().note_use();
} else {
System.err.println("Invalid terminal " + term_name +
" for contextual precedence assignment");
p = new production(context, lhs_nt, rhs_parts, rhs_pos);
p = new production(context, pr, lhs_nt, rhs_parts, rhs_pos);
}
pr.connectToInternalProduction(p);
Range range = Range.fromLocations(term_namexleft, term_namexright);
RESULT = new ProductionRight(p.index(),
p.get_embedded_actions(),
ast_get_rhs_parts_copy(),
new Terminal(
new Name(term_name, range),
(Range) range.clone()
),
Range.fromLocations(pplxleft, term_namexright));
// p.index();
RESULT = pr;
/* if we have no start non-terminal declared and this is
the first production, make its lhs nt the start_nt
......@@ -856,12 +860,12 @@ rhs ::=
if (!context.getXmlActions()) add_rhs_part(new action_part("RESULT = start_val;"));
if ((sym!=null) && (sym instanceof terminal)) {
context.start_production =
new production(context, non_terminal_shared.getSTART_nt(), rhs_parts,
new production(context, null, non_terminal_shared.getSTART_nt(), rhs_parts,
rhs_pos, ((terminal)sym).precedence_num(),
((terminal)sym).precedence_side());
} else {
context.start_production =
new production(context, non_terminal_shared.getSTART_nt(), rhs_parts, rhs_pos);
new production(context, null, non_terminal_shared.getSTART_nt(), rhs_parts, rhs_pos);
}
new_rhs();
ast_new_rhs();
......@@ -879,15 +883,16 @@ rhs ::=
if (lhs_nt != null)
{
/* build the production */
production p = new production(context, lhs_nt, rhs_parts, rhs_pos);
RESULT = new ProductionRight(p.index(),
p.get_embedded_actions(),
ProductionRight pr = new ProductionRight(
ast_get_rhs_parts_copy(),
null,
Range.fromLocations(pplxleft, pplxright));
/* build the production */
production p = new production(context, pr, lhs_nt, rhs_parts, rhs_pos);
pr.connectToInternalProduction(p);
RESULT = pr;
/* if we have no start non-terminal declared and this is
the first production, make its lhs nt the start_nt
......@@ -904,7 +909,7 @@ rhs ::=
add_rhs_part(new symbol_part(terminal_shared.getEOF()));
if (!context.getXmlActions()) add_rhs_part(new action_part("RESULT = start_val;"));
context.start_production =
new production(context, non_terminal_shared.getSTART_nt(), rhs_parts, rhs_pos);
new production(context, null, non_terminal_shared.getSTART_nt(), rhs_parts, rhs_pos);
new_rhs();
ast_new_rhs();
......
......@@ -11,6 +11,8 @@ public class ProductionRight extends AbstractNode {
private List<IProductionRightPart> lst;
private Terminal precedenceLike;
private production p;
private int index;
private List<Integer> extractedActionProductions;
......@@ -41,16 +43,19 @@ public class ProductionRight extends AbstractNode {
public production getMatchingInternal(CupContext context, int index) {
return production.getShared(context).find(index);
}
public ProductionRight(int index,
List<Integer> extractedActionProductions,
public void connectToInternalProduction(production p) {
this.p = p;
this.index = p.index();
this.extractedActionProductions = p.get_embedded_actions();
}
public ProductionRight(
List<IProductionRightPart> lst,
Terminal precedenceLike,
Range range) {
super(range);
this.precedenceLike = precedenceLike;
this.index = index;
this.extractedActionProductions = extractedActionProductions;
this.lst = lst;
if (lst != null) {
for (IProductionRightPart prp : lst) {
......
......@@ -2,6 +2,7 @@
package de.in.tum.www2.cup.internal;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.ast.ProductionRight;
/** A specialized version of a production used when we split an existing
* production in order to remove an embedded action. Here we keep a bit
......@@ -22,6 +23,7 @@ public class action_production extends production {
*/
public action_production(
CupContext context,
ProductionRight astNode,
production base,
non_terminal lhs_sym,
production_part rhs_parts[],
......@@ -30,7 +32,7 @@ public class action_production extends production {
int indexOfIntermediateResult)
throws internal_error
{
super(context, lhs_sym, rhs_parts, rhs_len, action_str);
super(context, astNode, lhs_sym, rhs_parts, rhs_len, action_str);
_base_production = base;
this.indexOfIntermediateResult = indexOfIntermediateResult;
}
......
......@@ -6,6 +6,7 @@ import java.util.Enumeration;
import java.util.ArrayList;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.ast.ProductionRight;
import de.in.tum.www2.cup.internal.non_terminal.non_terminal_shared;
import de.in.tum.www2.cup.internal.terminal.terminal_shared;
......@@ -32,6 +33,7 @@ import de.in.tum.www2.cup.internal.terminal.terminal_shared;
public class production {
private CupContext context;
private ProductionRight astNode;
private production_shared stat;
/*-----------------------------------------------------------*/
......@@ -63,6 +65,7 @@ public class production {
*/
public production(
CupContext context,
ProductionRight astNode,
non_terminal lhs_sym,
production_part rhs_parts[],
int rhs_l,
......@@ -70,7 +73,8 @@ public class production {
throws internal_error
{
this.context = context;
stat = context.getForContext(production_shared.class);
this.astNode = astNode;
this.stat = context.getForContext(production_shared.class);
_first_set = new terminal_set(context);
......@@ -179,12 +183,13 @@ public class production {
/** Constructor with no action string. */
public production(
CupContext context,
ProductionRight astNode,
non_terminal lhs_sym,
production_part rhs_parts[],
int rhs_l)
throws internal_error
{
this(context, lhs_sym,rhs_parts,rhs_l,null);
this(context, astNode, lhs_sym,rhs_parts,rhs_l,null);
}
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
......@@ -193,6 +198,7 @@ public class production {
contextually define */
public production(
CupContext context,
ProductionRight astNode,
non_terminal lhs_sym,
production_part rhs_parts[],
int rhs_l,
......@@ -201,7 +207,7 @@ public class production {
int prec_side)
throws internal_error
{
this(context, lhs_sym,rhs_parts,rhs_l,action_str);
this(context, astNode, lhs_sym,rhs_parts,rhs_l,action_str);
/* set the precedence */
set_precedence_num(prec_num);
......@@ -214,6 +220,7 @@ public class production {
defined */
public production(
CupContext context,
ProductionRight astNode,
non_terminal lhs_sym,
production_part rhs_parts[],
int rhs_l,
......@@ -221,7 +228,7 @@ public class production {
int prec_side)
throws internal_error
{
this(context, lhs_sym,rhs_parts,rhs_l,null);
this(context, astNode, lhs_sym,rhs_parts,rhs_l,null);
/* set the precedence */
set_precedence_num(prec_num);
set_precedence_side(prec_side);
......@@ -351,6 +358,10 @@ public class production {
return _embedded_actions;
}
// can be null.
public ProductionRight getAstNode() {
return astNode;
}
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
......@@ -635,7 +646,7 @@ public class production {
new_nt.is_embedded_action = true; /* 24-Mar-1998, CSA */
/* create a new production with just the action */
new_prod = new action_production(context, this, new_nt, null, 0,
new_prod = new action_production(context, astNode, this, new_nt, null, 0,
declare_str + ((action_part)rhs(act_loc)).code_string(), (lastLocation==-1)?-1:(act_loc-lastLocation));
eais.add(new_prod.index());
......
......@@ -46,13 +46,16 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
private static final int AUTO_EXPAND_L3_MAX_ITEMS = 100;
private static final int AUTO_EXPAND_L2_MAX_ITEMS = 500;
private Jumper jumper;
private CupTextEditor editor;
private IDocument doc;
private TreeViewer viewer;
private boolean suppressOnSelection;
private boolean suppressOnOutlineSelection;
private boolean suppressOnEditorSelection;
public CupContentOutlinePage(CupTextEditor editor) {
public CupContentOutlinePage(CupTextEditor editor, Jumper jumper) {
this.editor = editor;
this.jumper = jumper;
Controller.getInstance(editor).registerObserver(this);
doc = editor.getDocumentProvider().getDocument(editor.getEditorInput());
Model.getInstanceForDocument(doc).registerModelObserver(this);
......@@ -73,9 +76,9 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
Range range = node.getRange();
if (range.contains(pos)) {
ISelection selection = new StructuredSelection(node);
suppressOnSelection = true;
suppressOnEditorSelection = true;
viewer.setSelection(selection, true);
suppressOnSelection = false;
suppressOnEditorSelection = false;
return true;
}
} else {
......@@ -88,6 +91,8 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
}
public void jumpToPosition(Position pos) {
if (suppressOnOutlineSelection)
return;
if (viewer == null || pos == null)
return;
OutlineEntry root = (OutlineEntry) viewer.getInput();
......@@ -108,44 +113,16 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
@Override
public void selectionChanged(SelectionChangedEvent event) {
if (suppressOnSelection)
if (suppressOnEditorSelection)
return;
TreeSelection sel = (TreeSelection) event.getSelection();
OutlineEntry entry = (OutlineEntry) sel.getFirstElement();
if (entry == null)
return;
Range range = entry.getRange();
if (range == null)
return;
Position begin = range.getBegin();
if (begin == null)
return;
IDocument doc = editor.getDocumentProvider().getDocument(
editor.getEditorInput());
IRegion lineInfo = null;
try {
lineInfo = doc.getLineInformation(begin.getLine() - 1);
} catch (org.eclipse.jface.text.BadLocationException e) {
// ignore invalid line numbers
}
int from = lineInfo.getOffset();
int to = lineInfo.getLength();
// we currently only mark words if they are on the same line.
// otherwise we simply mark the whole line.
Position end = range.getEnd();
if (end != null && begin.getLine() == end.getLine()) {
from += begin.getColumn() - 1;
to = end.getColumn() - begin.getColumn();
}
if (lineInfo != null)
editor.selectAndReveal(from, to);
suppressOnOutlineSelection = true;
jumper.jumpToEditorSelection(entry.getRange());
suppressOnOutlineSelection = false;
}
private void updateFromResult(ParserResult result) {
......
......@@ -207,7 +207,7 @@ public class CupTextEditor extends TextEditor
public Object getAdapter(Class required) {
if (IContentOutlinePage.class.equals(required)) {
if (outlinePage == null)
outlinePage = new CupContentOutlinePage(this);
outlinePage = new CupContentOutlinePage(this, jumper);
return outlinePage;
}
......
package de.tum.in.www2.cupplugin.editors;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import de.in.tum.www2.cup.Position;
import de.in.tum.www2.cup.Range;
public class Jumper {
private MultiPageEditor mpe;
......@@ -7,5 +13,40 @@ public class Jumper {
Jumper (MultiPageEditor mpe) {
this.mpe = mpe;
}
public void jumpToEditorSelection(Range range) {
if (range == null)
return;
IDocument doc = mpe.getEditor().getDocument();
Position begin = range.getBegin();
if (begin == null)
return;
IRegion lineInfo = null;
try {
lineInfo = doc.getLineInformation(begin.getLine() - 1);
} catch (org.eclipse.jface.text.BadLocationException e) {
// ignore invalid line numbers
}
int from = lineInfo.getOffset();
int to = lineInfo.getLength();
// we currently only mark words if they are on the same line.
// otherwise we simply mark the whole line.
Position end = range.getEnd();
if (end != null && begin.getLine() == end.getLine()) {
from += begin.getColumn() - 1;
to = end.getColumn() - begin.getColumn();
}
if (lineInfo != null)
mpe.getEditor().selectAndReveal(from, to);
mpe.jumpTo(mpe.EDITOR_PAGE_INDEX);
}
}
......@@ -44,13 +44,13 @@ public class MultiPageEditor extends MultiPageEditorPart implements
private CupConflictGraphView conflictGraphView;
private CupReduceGraphView graphReduceView;
private final int OVERVIEW_PAGE_INDEX = 0;
private final int EDITOR_PAGE_INDEX = 1;
private final int CONFLICTS_PAGE_INDEX = 2;
private final int GRAPH_PAGE_INDEX = 3;
private final int ACTION_TABLE_PAGE_INDEX = 4;
private final int REDUCE_TABLE_PAGE_INDEX = 5;
private final int CONFLICT_GRAPH_PAGE_INDEX = 6;
public final int OVERVIEW_PAGE_INDEX = 0;
public final int EDITOR_PAGE_INDEX = 1;
public final int CONFLICTS_PAGE_INDEX = 2;
public final int GRAPH_PAGE_INDEX = 3;
public final int ACTION_TABLE_PAGE_INDEX = 4;
public final int REDUCE_TABLE_PAGE_INDEX = 5;
public final int CONFLICT_GRAPH_PAGE_INDEX = 6;
private int previousPageIndex = EDITOR_PAGE_INDEX;
......@@ -167,6 +167,10 @@ public class MultiPageEditor extends MultiPageEditorPart implements
setInput(editor.getEditorInput());
}
void jumpTo(int index) {
setActivePage(index);
}
public void gotoMarker(IMarker marker) {
setActivePage(EDITOR_PAGE_INDEX);
IDE.gotoMarker(getEditor(EDITOR_PAGE_INDEX), marker);
......
......@@ -7,6 +7,8 @@ import java.util.List;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
......@@ -14,6 +16,7 @@ import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import de.in.tum.www2.cup.Conflict;
import de.in.tum.www2.cup.ConflictManager;
......@@ -21,7 +24,10 @@ import de.in.tum.www2.cup.LALRResult;
import de.in.tum.www2.cup.ReduceReduceConflict;
import de.in.tum.www2.cup.ShiftReduceConflict;
import de.in.tum.www2.cup.ast.ParserResult;
import de.in.tum.www2.cup.ast.ProductionRight;
import de.in.tum.www2.cup.internal.internal_error;
import de.tum.in.www2.cupplugin.Colors;
import de.tum.in.www2.cupplugin.PluginUtility;
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;
......@@ -42,26 +48,29 @@ ICupParserLaLrChangeObserver, IRegisterForControllerChanges {
private ScrolledComposite scrolled;
private Composite list;
static class ConflictPanel extends Composite {
class ConflictPanel extends Composite {
private Label conflictTypeLabel;
private Label stateLabel;
private Link detailText;
public ConflictPanel(Composite parent, int style) {
super(parent, style);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
data.grabExcessHorizontalSpace = true;
data.heightHint = 50;
data.heightHint = 80;
setLayoutData(data);
setBackground(new Color(Display.getCurrent(), Colors.lightGray));
GridLayout layout = new GridLayout();
layout.numColumns = 5;
layout.numColumns = 3;
layout.verticalSpacing = 3;
setLayout(layout);
this.conflictTypeLabel = new Label(this, SWT.NONE);
this.stateLabel = new Label(this, SWT.NONE);
this.detailText = new Link(this, SWT.NONE);
this.detailText.setBackground(new Color(Display.getCurrent(), Colors.lightGray));
}
......@@ -69,12 +78,49 @@ ICupParserLaLrChangeObserver, IRegisterForControllerChanges {
if (conflict instanceof ReduceReduceConflict) {
conflictTypeLabel.setText("Reduce-Reduce conflict");
} else if (conflict instanceof ShiftReduceConflict) {
ShiftReduceConflict src = (ShiftReduceConflict) conflict;
conflictTypeLabel.setText("Shift-Reduce conflict");
ProductionRight conflict1Ast = src.getConflictItem1().the_production().getAstNode();
StringBuilder builder = new StringBuilder();
builder.append("Conflict between ");
builder.append("<a href=\"conflict1Production\">");
try {
builder.append(src.getConflictItem1().to_simple_string());
} catch (internal_error e1) {
e1.printStackTrace();
}
builder.append("</a>");
builder.append(" and other <a href=\"test2\">items</a>.");
detailText.setText(builder.toString());
detailText.setBackground(new Color(Display.getCurrent(), Colors.red));
detailText.setSize(400, 100);
// TODO: this MUST not be set here, because the link item is reused!
detailText.addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent e) {
if (e.text.equals("conflict1Production")) {
if (conflict1Ast != null)
jumper.jumpToEditorSelection(conflict1Ast.getRange());
else
PluginUtility.showMessage("This item does not have a matching AST node.");
}
System.out.println(e.text);
}
});
} else {
throw new RuntimeException("unexpected conflict type.");
}
stateLabel.setText("State: " + conflict.getState().index());
}
}
......
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