mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 16:58:56 +00:00
applied patch from bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=248463
This commit is contained in:
parent
bc8ef04c02
commit
13946fcd93
10 changed files with 214 additions and 72 deletions
|
@ -114,6 +114,10 @@ public class GrammarUtil {
|
|||
public static List<Keyword> containedKeywords(EObject e) {
|
||||
return getAllContentsOfType(e, Keyword.class);
|
||||
}
|
||||
|
||||
public static List<CrossReference> containedCrossReferences(EObject e) {
|
||||
return getAllContentsOfType(e, CrossReference.class);
|
||||
}
|
||||
|
||||
public static List<AbstractElement> elementsBeforeThisInContainingGroup(AbstractElement _this) {
|
||||
Group g = containingGroup(_this);
|
||||
|
|
|
@ -38,6 +38,8 @@ context GeneratedMetamodel ERROR "Duplicate aliases are only allowed for referen
|
|||
|
||||
context AbstractRule ERROR "Name must be unique" :
|
||||
grammar().rules.select(p | p.name == name).size==1;
|
||||
|
||||
// TODO: check that CrossReferences can only appear inside Assignments
|
||||
|
||||
/*
|
||||
context ParserRule ERROR "Returned class " + getReturnTypeName() + " cannot be resolved" :
|
||||
|
|
|
@ -24,7 +24,7 @@ public interface IInstanceDescription {
|
|||
* language
|
||||
* @return true if the delegate's type is assignable to the given type
|
||||
*/
|
||||
public abstract boolean isOfType(String string);
|
||||
// public abstract boolean isOfType(String string);
|
||||
|
||||
/**
|
||||
* @return the wrapped EObject
|
||||
|
@ -37,8 +37,15 @@ public interface IInstanceDescription {
|
|||
* @param feature
|
||||
* @return the consumed value
|
||||
*/
|
||||
public abstract Object get(String feature);
|
||||
// public abstract Object get(String feature);
|
||||
|
||||
public Object getConsumable(String feature, boolean allowDefault);
|
||||
|
||||
public IInstanceDescription cloneAndConsume(String feature);
|
||||
|
||||
public boolean isConsumedWithLastConsumtion(String feature);
|
||||
|
||||
@Deprecated
|
||||
public Object consume(String feature);
|
||||
|
||||
/**
|
||||
|
@ -46,18 +53,22 @@ public interface IInstanceDescription {
|
|||
* @param feature
|
||||
* @return whether there are any consumable values for the given feature
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract boolean isConsumable(String feature);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return whether all values referenced by the delegate have been consumed
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract boolean isConsumed();
|
||||
|
||||
/**
|
||||
* @param feature
|
||||
* @return the number of values already consumed for this feature
|
||||
*/
|
||||
public abstract int getConsumed(String feature);
|
||||
// public abstract int getConsumed(String feature);
|
||||
|
||||
public IInstanceDescription createClone();
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ package org.eclipse.xtext.parsetree.reconstr;
|
|||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.Action;
|
||||
import org.eclipse.xtext.CrossReference;
|
||||
import org.eclipse.xtext.Keyword;
|
||||
|
@ -34,8 +35,11 @@ public interface IParseTreeConstructorCallback extends ILanguageService {
|
|||
|
||||
void actionCall(IInstanceDescription oldCurrent,
|
||||
IInstanceDescription newCurrent, Action action);
|
||||
|
||||
|
||||
@Deprecated
|
||||
void crossRefCall(IInstanceDescription current, CrossReference call);
|
||||
|
||||
void crossRefCall(IInstanceDescription current, CrossReference call, EObject value);
|
||||
|
||||
void beginSerialize(OutputStream output);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.eclipse.xtext.parsetree.reconstr.callbacks;
|
|||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.Action;
|
||||
import org.eclipse.xtext.CrossReference;
|
||||
import org.eclipse.xtext.Keyword;
|
||||
|
@ -48,4 +49,7 @@ public class DefaultParsetreeReconstructorCallback implements IParseTreeConstruc
|
|||
|
||||
public void endSerialize() {
|
||||
}
|
||||
|
||||
public void crossRefCall(IInstanceDescription current, CrossReference call, EObject value) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,7 @@ import java.io.OutputStream;
|
|||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.AbstractElement;
|
||||
import org.eclipse.xtext.Assignment;
|
||||
import org.eclipse.xtext.CrossReference;
|
||||
import org.eclipse.xtext.GrammarUtil;
|
||||
import org.eclipse.xtext.Keyword;
|
||||
import org.eclipse.xtext.RuleCall;
|
||||
import org.eclipse.xtext.conversion.IValueConverterService;
|
||||
|
@ -18,7 +16,8 @@ import org.eclipse.xtext.service.Inject;
|
|||
public class SimpleSerializingCallback extends
|
||||
DefaultParsetreeReconstructorCallback {
|
||||
|
||||
static final Logger logger = Logger.getLogger(SimpleSerializingCallback.class);
|
||||
static final Logger logger = Logger
|
||||
.getLogger(SimpleSerializingCallback.class);
|
||||
|
||||
@Inject
|
||||
protected IValueConverterService converterService;
|
||||
|
@ -49,22 +48,11 @@ public class SimpleSerializingCallback extends
|
|||
outputHasStarted = false;
|
||||
out = output;
|
||||
}
|
||||
|
||||
public void crossRefCall(IInstanceDescription current, CrossReference call) {
|
||||
logger.debug("crossRefCall(" + call + ")");
|
||||
Assignment ass = GrammarUtil.containingAssignment(call);
|
||||
if (ass == null)
|
||||
throw new IllegalStateException("Unassigned cross reference "
|
||||
+ call);
|
||||
Object object = current.get(ass.getFeature());
|
||||
if (object instanceof EObject) {
|
||||
EObject obj = (EObject) object;
|
||||
// prepend(obj.eResource().getURIFragment(obj));
|
||||
before(current, call);
|
||||
append(obj.eResource().getURIFragment(obj));
|
||||
}
|
||||
throw new IllegalStateException("Can't serialize cross reference to "
|
||||
+ object);
|
||||
|
||||
public void crossRefCall(IInstanceDescription current, CrossReference call,
|
||||
EObject value) {
|
||||
before(current, call);
|
||||
append(value.eResource().getURIFragment(value));
|
||||
}
|
||||
|
||||
public IValueConverterService getConverterService() {
|
||||
|
|
|
@ -8,8 +8,12 @@ import java.util.Map;
|
|||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.AbstractElement;
|
||||
import org.eclipse.xtext.CrossReference;
|
||||
import org.eclipse.xtext.Grammar;
|
||||
import org.eclipse.xtext.IGrammarAccess;
|
||||
import org.eclipse.xtext.Keyword;
|
||||
import org.eclipse.xtext.RuleCall;
|
||||
import org.eclipse.xtext.conversion.IValueConverterService;
|
||||
import org.eclipse.xtext.parser.IAstFactory;
|
||||
import org.eclipse.xtext.parsetree.reconstr.IInstanceDescription;
|
||||
|
@ -19,10 +23,15 @@ import org.eclipse.xtext.service.Inject;
|
|||
|
||||
public abstract class AbstractParseTreeConstructor implements
|
||||
IParseTreeConstructor {
|
||||
|
||||
protected enum AssignmentType {
|
||||
KW, PRC, LRC, CR
|
||||
};
|
||||
|
||||
public abstract class AbstractToken {
|
||||
|
||||
public class Solution {
|
||||
private final InstanceDescription current;
|
||||
private final IInstanceDescription current;
|
||||
private final AbstractToken predecessor;
|
||||
|
||||
public Solution() {
|
||||
|
@ -37,20 +46,20 @@ public abstract class AbstractParseTreeConstructor implements
|
|||
this.predecessor = predecessor;
|
||||
}
|
||||
|
||||
public Solution(final InstanceDescription current) {
|
||||
public Solution(final IInstanceDescription current) {
|
||||
super();
|
||||
this.current = current;
|
||||
this.predecessor = AbstractToken.this;
|
||||
}
|
||||
|
||||
public Solution(InstanceDescription current,
|
||||
public Solution(IInstanceDescription current,
|
||||
AbstractToken predecessor) {
|
||||
super();
|
||||
this.current = current;
|
||||
this.predecessor = predecessor;
|
||||
}
|
||||
|
||||
public InstanceDescription getCurrent() {
|
||||
public IInstanceDescription getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
|
@ -61,13 +70,13 @@ public abstract class AbstractParseTreeConstructor implements
|
|||
|
||||
protected final static boolean IS_MANY = true;
|
||||
protected final static boolean IS_REQUIRED = true;
|
||||
protected final InstanceDescription current;
|
||||
protected final IInstanceDescription current;
|
||||
protected final boolean many;
|
||||
protected Solution otherSolution;
|
||||
protected final AbstractToken predecessor;
|
||||
protected final boolean required;
|
||||
|
||||
public AbstractToken(InstanceDescription curr, AbstractToken pred,
|
||||
public AbstractToken(IInstanceDescription curr, AbstractToken pred,
|
||||
boolean many, boolean required) {
|
||||
super();
|
||||
this.current = curr;
|
||||
|
@ -146,12 +155,12 @@ public abstract class AbstractParseTreeConstructor implements
|
|||
return t1;
|
||||
}
|
||||
|
||||
protected AbstractToken newInstance(InstanceDescription curr,
|
||||
protected AbstractToken newInstance(IInstanceDescription curr,
|
||||
AbstractToken pred) {
|
||||
try {
|
||||
Constructor<?> c = getClass().getConstructor(
|
||||
getClass().getEnclosingClass(),
|
||||
InstanceDescription.class, AbstractToken.class);
|
||||
IInstanceDescription.class, AbstractToken.class);
|
||||
return (AbstractToken) c.newInstance(
|
||||
AbstractParseTreeConstructor.this, curr, pred);
|
||||
} catch (SecurityException e) {
|
||||
|
@ -182,34 +191,63 @@ public abstract class AbstractParseTreeConstructor implements
|
|||
|
||||
public abstract class ActionToken extends AbstractToken {
|
||||
|
||||
public ActionToken(InstanceDescription curr, AbstractToken pred,
|
||||
public ActionToken(IInstanceDescription curr, AbstractToken pred,
|
||||
boolean many, boolean required) {
|
||||
super(curr, pred, many, required);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract class AlternativeToken extends AbstractToken {
|
||||
public abstract class AlternativesToken extends AbstractToken {
|
||||
|
||||
public AlternativeToken(InstanceDescription curr, AbstractToken pred,
|
||||
protected boolean first = true;
|
||||
|
||||
public AlternativesToken(IInstanceDescription curr, AbstractToken pred,
|
||||
boolean many, boolean required) {
|
||||
super(curr, pred, many, required);
|
||||
}
|
||||
|
||||
protected boolean activateNextSolution() {
|
||||
if (first) {
|
||||
first = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class AssignmentToken extends AbstractToken {
|
||||
protected AbstractElement element;
|
||||
protected Object value;
|
||||
protected AssignmentType type;
|
||||
|
||||
public AssignmentToken(InstanceDescription curr, AbstractToken pred,
|
||||
public AssignmentToken(IInstanceDescription curr, AbstractToken pred,
|
||||
boolean many, boolean required) {
|
||||
super(curr, pred, many, required);
|
||||
}
|
||||
|
||||
public void executeCallback(IParseTreeConstructorCallback callback) {
|
||||
if (type != null)
|
||||
switch (type) {
|
||||
case KW:
|
||||
callback.keywordCall(current, (Keyword) element);
|
||||
return;
|
||||
case PRC: /* noting to do for parser rule calls */
|
||||
return;
|
||||
case LRC:
|
||||
callback.lexerRuleCall(current, (RuleCall) element, value);
|
||||
return;
|
||||
case CR:
|
||||
callback.crossRefCall(current, (CrossReference) element,
|
||||
(EObject) value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class GroupToken extends AbstractToken {
|
||||
|
||||
public GroupToken(InstanceDescription curr, AbstractToken pred,
|
||||
public GroupToken(IInstanceDescription curr, AbstractToken pred,
|
||||
boolean many, boolean required) {
|
||||
super(curr, pred, many, required);
|
||||
}
|
||||
|
@ -218,7 +256,7 @@ public abstract class AbstractParseTreeConstructor implements
|
|||
|
||||
public abstract class KeywordToken extends AbstractToken {
|
||||
|
||||
public KeywordToken(InstanceDescription curr, AbstractToken pred,
|
||||
public KeywordToken(IInstanceDescription curr, AbstractToken pred,
|
||||
boolean many, boolean required) {
|
||||
super(curr, pred, many, required);
|
||||
}
|
||||
|
@ -227,7 +265,7 @@ public abstract class AbstractParseTreeConstructor implements
|
|||
|
||||
public abstract class RuleCallToken extends AbstractToken {
|
||||
|
||||
public RuleCallToken(InstanceDescription curr, AbstractToken pred,
|
||||
public RuleCallToken(IInstanceDescription curr, AbstractToken pred,
|
||||
boolean many, boolean required) {
|
||||
super(curr, pred, many, required);
|
||||
}
|
||||
|
@ -248,7 +286,7 @@ public abstract class AbstractParseTreeConstructor implements
|
|||
@Inject
|
||||
private IGrammarAccess grammar;
|
||||
|
||||
protected final InstanceDescription getDescr(EObject obj) {
|
||||
protected final IInstanceDescription getDescr(EObject obj) {
|
||||
return new InstanceDescription(this, obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,23 +29,33 @@ public class InstanceDescription implements IInstanceDescription {
|
|||
*/
|
||||
public AbstractParseTreeConstructor parseTreeConstr;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.xtext.parsetree.impl.IInstanceDescription#isInstanceOf(java.lang.String)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.xtext.parsetree.impl.IInstanceDescription#isInstanceOf(java
|
||||
* .lang.String)
|
||||
*/
|
||||
public boolean isInstanceOf(String string) {
|
||||
EClass class1 = this.parseTreeConstr.getFactory().getEClass(string);
|
||||
return class1 != null && class1.isSuperTypeOf(getDelegate().eClass());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.xtext.parsetree.impl.IInstanceDescription#isOfType(java.lang.String)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.xtext.parsetree.impl.IInstanceDescription#isOfType(java.lang
|
||||
* .String)
|
||||
*/
|
||||
public boolean isOfType(String string) {
|
||||
EClass class1 = this.parseTreeConstr.getFactory().getEClass(string);
|
||||
return class1 != null && class1.equals(getDelegate().eClass());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.xtext.parsetree.impl.IInstanceDescription#getDelegate()
|
||||
*/
|
||||
public EObject getDelegate() {
|
||||
|
@ -55,13 +65,16 @@ public class InstanceDescription implements IInstanceDescription {
|
|||
public EObject described;
|
||||
public Map<String, Integer> featureConsumedCounter = new HashMap<String, Integer>();
|
||||
|
||||
public InstanceDescription(AbstractParseTreeConstructor abstractInternalParseTreeConstructor, EObject described) {
|
||||
public InstanceDescription(
|
||||
AbstractParseTreeConstructor abstractInternalParseTreeConstructor,
|
||||
EObject described) {
|
||||
super();
|
||||
this.parseTreeConstr = abstractInternalParseTreeConstructor;
|
||||
if (described == null)
|
||||
throw new NullPointerException("described");
|
||||
this.described = described;
|
||||
EList<EStructuralFeature> features = described.eClass().getEAllStructuralFeatures();
|
||||
EList<EStructuralFeature> features = described.eClass()
|
||||
.getEAllStructuralFeatures();
|
||||
for (EStructuralFeature f : features) {
|
||||
Integer integer = 0;
|
||||
if (described.eIsSet(f)) {
|
||||
|
@ -75,15 +88,15 @@ public class InstanceDescription implements IInstanceDescription {
|
|||
}
|
||||
}
|
||||
|
||||
private InstanceDescription(AbstractParseTreeConstructor abstractInternalParseTreeConstructor, EObject described, Map<String, Integer> featureConsumedCounter) {
|
||||
private InstanceDescription(
|
||||
AbstractParseTreeConstructor abstractInternalParseTreeConstructor,
|
||||
EObject described, Map<String, Integer> featureConsumedCounter) {
|
||||
super();
|
||||
this.parseTreeConstr = abstractInternalParseTreeConstructor;
|
||||
this.described = described;
|
||||
this.featureConsumedCounter = featureConsumedCounter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
List<String> l = new ArrayList<String>();
|
||||
|
@ -122,9 +135,13 @@ public class InstanceDescription implements IInstanceDescription {
|
|||
featureConsumedCounter.put(feature, counter - 1);
|
||||
return get;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.xtext.parsetree.impl.IInstanceDescription#get(java.lang.String)
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.xtext.parsetree.impl.IInstanceDescription#get(java.lang.String
|
||||
* )
|
||||
*/
|
||||
public Object get(String feature) {
|
||||
Integer counter = lazyGet(feature);
|
||||
|
@ -163,14 +180,20 @@ public class InstanceDescription implements IInstanceDescription {
|
|||
return described.eClass().getEStructuralFeature(feature);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.xtext.parsetree.impl.IInstanceDescription#isConsumable(java.lang.String)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.xtext.parsetree.impl.IInstanceDescription#isConsumable(java
|
||||
* .lang.String)
|
||||
*/
|
||||
public boolean isConsumable(String feature) {
|
||||
return lazyGet(feature) > 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.xtext.parsetree.impl.IInstanceDescription#isConsumed()
|
||||
*/
|
||||
public boolean isConsumed() {
|
||||
|
@ -182,21 +205,25 @@ public class InstanceDescription implements IInstanceDescription {
|
|||
}
|
||||
|
||||
public IInstanceDescription createClone() {
|
||||
return new InstanceDescription(this.parseTreeConstr, described, new HashMap<String, Integer>(featureConsumedCounter));
|
||||
return new InstanceDescription(this.parseTreeConstr, described,
|
||||
new HashMap<String, Integer>(featureConsumedCounter));
|
||||
}
|
||||
|
||||
public int getConsumed(String feature) {
|
||||
EStructuralFeature feature2 = described.eClass().getEStructuralFeature(feature);
|
||||
EStructuralFeature feature2 = described.eClass().getEStructuralFeature(
|
||||
feature);
|
||||
if (feature2.isMany()) {
|
||||
return ((Collection<?>)described.eGet(feature2)).size()-featureConsumedCounter.get(feature);
|
||||
return ((Collection<?>) described.eGet(feature2)).size()
|
||||
- featureConsumedCounter.get(feature);
|
||||
}
|
||||
return 1-featureConsumedCounter.get(feature);
|
||||
return 1 - featureConsumedCounter.get(feature);
|
||||
}
|
||||
|
||||
|
||||
public String uniqueStateString() {
|
||||
StringBuffer buff = new StringBuffer();
|
||||
buff.append(getDelegate());
|
||||
List<String> features = new ArrayList<String>(featureConsumedCounter.keySet());
|
||||
List<String> features = new ArrayList<String>(featureConsumedCounter
|
||||
.keySet());
|
||||
Collections.sort(features);
|
||||
for (String f : features) {
|
||||
buff.append(f).append(featureConsumedCounter.get(f));
|
||||
|
@ -204,4 +231,37 @@ public class InstanceDescription implements IInstanceDescription {
|
|||
return buff.toString();
|
||||
}
|
||||
|
||||
public IInstanceDescription cloneAndConsume(String feature) {
|
||||
InstanceDescription inst = new InstanceDescription(
|
||||
this.parseTreeConstr, described, new HashMap<String, Integer>(
|
||||
featureConsumedCounter));
|
||||
inst.featureConsumedCounter.put(feature, inst.lazyGet(feature) - 1);
|
||||
return inst;
|
||||
}
|
||||
|
||||
public Object getConsumable(String feature, boolean allowDefault) {
|
||||
EStructuralFeature f = getFeature(feature);
|
||||
if (f != null
|
||||
&& (isConsumable(feature) || (allowDefault && !f.isMany()))) {
|
||||
Integer counter = lazyGet(feature);
|
||||
Object get = described.eGet(f);
|
||||
if (f.isMany()) {
|
||||
List<?> list = (List<?>) get;
|
||||
get = list.get(counter - 1);
|
||||
}
|
||||
return get;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isConsumedWithLastConsumtion(String feature) {
|
||||
for (Entry<String, Integer> e : featureConsumedCounter.entrySet()) {
|
||||
Integer i = (e.getKey().equals(feature)) ? e.getValue() - 1 : e
|
||||
.getValue();
|
||||
if (i > 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -11,7 +11,6 @@ package org.eclipse.xtext.parsetree.reconstr;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.parsetree.NodeUtil;
|
||||
import org.eclipse.xtext.testlanguages.SimpleExpressionsStandaloneSetup;
|
||||
|
@ -19,8 +18,6 @@ import org.eclipse.xtext.tests.AbstractGeneratorTest;
|
|||
import org.eclipse.xtext.util.EmfFormater;
|
||||
|
||||
public class SimpleReconstrTest extends AbstractGeneratorTest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SimpleReconstrTest.class);
|
||||
|
||||
public void testSimple1() throws Exception {
|
||||
String model = "a b";
|
||||
|
@ -44,10 +41,10 @@ public class SimpleReconstrTest extends AbstractGeneratorTest {
|
|||
|
||||
private String parseAndSerialize(String model) throws Exception {
|
||||
EObject result = (EObject) getModel(model);
|
||||
logger.debug(EmfFormater.objToStr(result, ""));
|
||||
logger.debug(EmfFormater.objToStr(NodeUtil.getRootNode(result),
|
||||
System.out.println(EmfFormater.objToStr(result, ""));
|
||||
System.out.println(EmfFormater.objToStr(NodeUtil.getRootNode(result),
|
||||
""));
|
||||
logger.debug(EmfFormater.objToStr(NodeUtil.getRootNode(result)
|
||||
System.out.println(EmfFormater.objToStr(NodeUtil.getRootNode(result)
|
||||
.getLeafNodes(), ""));
|
||||
|
||||
IParseTreeConstructor con = getParseTreeConstructor();
|
||||
|
@ -72,6 +69,16 @@ public class SimpleReconstrTest extends AbstractGeneratorTest {
|
|||
String model = "2 45";
|
||||
assertEquals(model, parseAndSerialize(model));
|
||||
}
|
||||
|
||||
public void testSimpleTwoNumbersWithDefault() throws Exception {
|
||||
String model = "0 45";
|
||||
assertEquals(model, parseAndSerialize(model));
|
||||
}
|
||||
|
||||
public void testSimpleTwoNumbersWithDefault2() throws Exception {
|
||||
String model = "0 45 # 0 # 1 # 2";
|
||||
assertEquals(model, parseAndSerialize(model));
|
||||
}
|
||||
|
||||
public void testSimpleManyStrings1() throws Exception {
|
||||
String model = "= 'xxx' 'yyy'";
|
||||
|
@ -83,6 +90,24 @@ public class SimpleReconstrTest extends AbstractGeneratorTest {
|
|||
assertEquals(model, parseAndSerialize(model));
|
||||
}
|
||||
|
||||
public void testSimpleAlternativeAssignment1() throws Exception {
|
||||
String model = "#2 mykeyword1";
|
||||
assertEquals(model, parseAndSerialize(model));
|
||||
}
|
||||
|
||||
// FIXME: this depends on
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=250313
|
||||
// public void testSimpleAlternativeAssignment2() throws Exception {
|
||||
// String model = "#2 'str'";
|
||||
// assertEquals(model, parseAndSerialize(model));
|
||||
// }
|
||||
|
||||
// FIXME: make this work
|
||||
// public void testCrossRef() throws Exception {
|
||||
// String model = "type A extends B type B extends A";
|
||||
// assertEquals(model, parseAndSerialize(model));
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
with(SimpleReconstrTestStandaloneSetup.class);
|
||||
|
|
|
@ -13,7 +13,7 @@ Op returns Expression:
|
|||
Term ({Op.values+=current} values+=Term)*;
|
||||
|
||||
Term returns Expression:
|
||||
Atom | TwoNumbers | ManyStrings | Parens;
|
||||
Atom | TwoNumbers | ManyStrings | Parens | Type | Ref2;
|
||||
|
||||
Atom:
|
||||
name=ID;
|
||||
|
@ -22,9 +22,15 @@ Parens returns Expression:
|
|||
'(' Op ')' em='!'?;
|
||||
|
||||
TwoNumbers:
|
||||
num1=INT num2=INT;
|
||||
|
||||
ManyStrings: '=' (str1+=STRING)* str2+=STRING;
|
||||
|
||||
num1=INT num2=INT ('#' num3+=INT)*;
|
||||
|
||||
ManyStrings:
|
||||
'=' (str1+=STRING)* str2+=STRING;
|
||||
|
||||
Type :
|
||||
'type' name=ID 'extends' ^extends=[Type];
|
||||
|
||||
Ref2:
|
||||
'#2' ref2=('mykeyword1' | STRING | 'mykeyword2') ;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue