Backtrack and Formatting bug? [message #924043] |
Wed, 26 September 2012 12:47 |
Sandra Shklyaeva Messages: 16 Registered: July 2012 |
Junior Member |
|
|
During the developing, I found the following strange behavior that looks like a bug.
When I turn on the backtracking for MyDsl, formatting fails in the places where backtrack is needed.
When I turn off the backtrack, formatting works as expected.
I attached ready-to-use MyDsl projects with the grammar and formatting.
I also added the project with MyDsl file which reproduce the behavior.
For example, when the backtrack is not needed, formatting is:
for X in Z do
for X in Z do
for X in Z do
//backtrack is not needed
X + Y
end ;
end ;
end ;
When the backtrack is needed, formatting fails:
for X in Z do
for X in Z do
for X in Z do
//back track is needed
X => Y end
;
end
;
end ;
The grammar is:
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "MyDsl"
Model:
(statemets+=Statement ';')*;
Block:
statemets+=Statement (';' statemets+=Statement?)*;
Statement:
For |
Import |
AssignExpr;
Sequence:
expressions+=Expression (',' expressions+=Expression)*;
Import:
'import' imports+=ImportItem (',' imports+=ImportItem)*
=>'in' block=Block? 'end';
ImportItem:
name=[Declaration] ('=' value=Expression)?;
Name:
name=[Declaration];
Parameter returns Declaration:
{Parameter} name=ID (=>'=' value=Expression)?;
Var returns Declaration:
{Local} 'var' name=ID (=>'=' value=Expression)?;
Declaration:
Var | Parameter | Rule;
Rule returns Declaration:
{Rule} (
'(' (parameters+=Parameter (',' parameters+=Parameter)*)? ')' name=ID? |
parameters+=Parameter
) '=>' body = EqualityExpression;
AssignExpr returns Expression:
Sequence ({Assign.left = current} 'assing' right=Sequence)?;
Expression:
EqualityExpression ({Plus.left = current} '+' right=EqualityExpression)?;
EqualityExpression returns Expression:
FactorialExpression (
(
{In.left = current} 'in' |
{Equal.left = current} =>'=='
)
right=FactorialExpression
)?;
FactorialExpression returns Expression:
PrimaryExpression ({Factorial.expression = current} '!' )?;
PrimaryExpression returns Expression:
Primary ({Function.scope = current} '(' args = Sequence? ')')*;
Primary returns Expression:
Var |
Rule |
Name |
Enclosed |
Literal;
Literal:
{Literal} (STRING | INT);
Enclosed:
{Enclosed} '(' args = Sequence? ')';
For:
'for' name=Name 'in' inExpr=Sequence 'do' body=Block? 'end';
The formatting is:
/*
* generated by Xtext
*/
package org.xtext.example.mydsl.formatting;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.formatting.impl.AbstractDeclarativeFormatter;
import org.eclipse.xtext.formatting.impl.FormattingConfig;
import org.eclipse.xtext.util.Pair;
import org.xtext.example.mydsl.services.MyDslGrammarAccess;
/**
* This class contains custom formatting description.
*
* see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#formatting
* on how and when to use it
*
* Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an
* example
*/
public class MyDslFormatter extends AbstractDeclarativeFormatter {
@Override
protected void configureFormatting(FormattingConfig c) {
MyDslGrammarAccess f = (MyDslGrammarAccess) getGrammarAccess();
// formatting for Comments
c.setLinewrap(0, 1, 2).before(f.getSL_COMMENTRule());
c.setLinewrap(0, 1, 2).before(f.getML_COMMENTRule());
c.setLinewrap(0, 1, 1).after(f.getML_COMMENTRule());
// find common keywords an specify formatting for them
for (Pair<Keyword, Keyword> pair : f.findKeywordPairs("(", ")")) {
c.setNoSpace().after(pair.getFirst());
c.setNoSpace().before(pair.getSecond());
}
for (Keyword keyword : f.findKeywords(",")) {
c.setNoSpace().before(keyword);
}
// spaces between statements in compilation unit
c.setLinewrap(2).after(f.getModelAccess().getSemicolonKeyword_1());
c.setNoSpace().before(
f.getPrimaryExpressionAccess().getLeftParenthesisKeyword_1_1());
c.setNoSpace().before(
f.getPrimaryExpressionAccess().getLeftParenthesisKeyword_1_1());
// block formating
ParserRule blockRule = f.getBlockRule();
c.setLinewrap().before(blockRule);
c.setIndentationIncrement().before(blockRule);
c.setLinewrap().after(blockRule);
c.setIndentationDecrement().after(blockRule);
c.setLinewrap().after(f.getBlockAccess().getSemicolonKeyword_1_0());
}
}
-
Attachment: MyDsl.zip
(Size: 385.37KB, Downloaded 182 times)
|
|
|
|
|
|
|
Re: Backtrack and Formatting bug? [message #936554 is a reply to message #924043] |
Mon, 08 October 2012 05:20 |
Sandra Shklyaeva Messages: 16 Registered: July 2012 |
Junior Member |
|
|
After all I found the solution. Unfortunately the solution is dirty hack, but it works!
In the class org.eclipse.xtext.formatting.impl.ElementMatcherProvider I commented out the following if in the findTransitionPath method.
With this hack, backtracking doesn't break formatting and all works as expected.
What is the purpose of this if? I still cannot understand why it's needed.
protected Pair<List<MatcherTransition>, List<MatcherState>> findTransitionPath(MatcherState from, AbstractElement to, boolean returning, boolean canReturn, Set<Pair<Boolean, MatcherState>> visited) {
// if (!visited.add(Tuples.create(returning, from)))
// return null;
if (from != null) { ...
OR even
protected Pair<List<MatcherTransition>, List<MatcherState>> findTransitionPath(MatcherState from, AbstractElement to, boolean returning, boolean canReturn, Set<Pair<Boolean, MatcherState>> visited) {
if (!visited.add(Tuples.create(returning, from))) {
// return null;
}
if (from != null) { ...
[Updated on: Mon, 08 October 2012 05:34] Report message to a moderator
|
|
|
Powered by
FUDForum. Page generated in 0.03276 seconds