use of org.eclipse.xtext.serializer.analysis.ISemanticSequencerNfaProvider.ISemState in project xtext-core by eclipse.
the class BacktrackingSemanticSequencer method createSequence.
@Override
public void createSequence(ISerializationContext context, EObject obj) {
INodesForEObjectProvider nodes = nodeProvider.getNodesForSemanticObject(obj, null);
SerializationContextMap<IConstraint> constraints = constraintProvider.getConstraints(grammar.getGrammar());
IConstraint constraint = constraints.get(context);
if (constraint == null)
throw new IllegalStateException("Invalid context: " + context);
Nfa<ISemState> nfa = constraint.getNfa();
final SerializableObject object = new SerializableObject(context, obj, nodes);
TraceItem co = new TraceItem(object);
List<TraceItem> trace = new NfaUtil().backtrack(nfa, co, new NfaUtil.BacktrackHandler<ISemState, TraceItem>() {
@Override
public TraceItem handle(ISemState state, TraceItem previous) {
if (!previous.canEnter(state))
return null;
if (state.getFeature() != null) {
return previous.cloneAndConsume(state);
} else
return previous.clone(state);
}
@Override
public boolean isSolution(TraceItem result) {
return result.isConsumed();
}
@Override
public Iterable<ISemState> sortFollowers(TraceItem result, Iterable<ISemState> followers) {
AbstractElement next = result.getNextGrammarElement();
List<ISemState> r = Lists.newArrayList(followers);
Collections.sort(r, createFollowerSorter(object, next));
return r;
}
});
SequenceFeeder feeder = feederProvider.create(context, obj, nodes, masterSequencer, sequenceAcceptor, errorAcceptor);
if (trace != null) {
for (TraceItem ti : trace) if (ti.getState() != null && ti.getState().getFeature() != null)
accept(ti, feeder);
} else if (errorAcceptor != null)
errorAcceptor.accept(diagnosticProvider.createBacktrackingFailedDiagnostic(object, context, constraint));
feeder.finish();
}
use of org.eclipse.xtext.serializer.analysis.ISemanticSequencerNfaProvider.ISemState in project xtext-core by eclipse.
the class GrammarConstraintProvider method getConstraints.
@Override
public SerializationContextMap<IConstraint> getConstraints(Grammar grammar) {
SerializationContextMap<IConstraint> cached = cache.get(grammar);
if (cached != null)
return cached;
SerializationContextMap.Builder<IConstraint> builder = SerializationContextMap.builder();
GrammarElementDeclarationOrder.get(grammar);
SerializationContextMap<Nfa<ISemState>> nfas = nfaProvider.getSemanticSequencerNFAs(grammar);
for (Entry<Nfa<ISemState>> e : nfas.values()) {
Nfa<ISemState> nfa = e.getValue();
for (EClass type : e.getTypes()) {
Constraint constraint = new Constraint(grammar, type, nfa);
List<ISerializationContext> contexts = e.getContexts(type);
constraint.contexts.addAll(contexts);
builder.put(contexts, constraint);
}
}
SerializationContextMap<IConstraint> result = builder.create();
SerializationContextMap<Pda<ISerState, RuleCall>> typePDAs = typeProvider.getContextTypePDAs(grammar);
for (Entry<IConstraint> e : result.values()) {
Constraint constraint = (Constraint) e.getValue();
constraint.setName(findBestConstraintName(grammar, typePDAs, constraint));
}
cache.put(grammar, result);
return result;
}
use of org.eclipse.xtext.serializer.analysis.ISemanticSequencerNfaProvider.ISemState in project xtext-core by eclipse.
the class GrammarConstraintProvider method findBestConstraintName.
protected String findBestConstraintName(Grammar grammar, SerializationContextMap<Pda<ISerState, RuleCall>> typePDAs, IConstraint constraint) {
Set<ParserRule> relevantRules = Sets.newLinkedHashSet();
Set<Action> relevantActions = Sets.newLinkedHashSet();
Set<ParserRule> contextRules = Sets.newLinkedHashSet();
for (ISerializationContext ctx : constraint.getContexts()) {
ParserRule rule = ctx.getParserRule();
if (rule != null) {
contextRules.add(rule);
}
}
// 1. find relevant rules based on assignments
for (ISemState s : nfaUtil.collect(constraint.getNfa())) {
AbstractElement element = s.getAssignedGrammarElement();
if (element != null)
relevantRules.add(GrammarUtil.containingParserRule(element));
}
// 2. find relevant rules based on unassigned actions
for (ISerializationContext ctx : constraint.getContexts()) {
for (ISerState s : nfaUtil.collect(typePDAs.get(ctx))) {
AbstractElement element = s.getGrammarElement();
if (element instanceof Action && ((Action) element).getFeature() == null)
relevantRules.add(GrammarUtil.containingParserRule(element));
}
}
if (relevantRules.isEmpty()) {
Set<ParserRule> allRules = Sets.newLinkedHashSet(contextRules);
for (ISerializationContext ctx : constraint.getContexts()) {
Action action = ctx.getAssignedAction();
if (action != null)
allRules.add(GrammarUtil.containingParserRule(action));
}
// 3. use all rules, because the constraint returns null.
relevantRules.addAll(allRules);
}
for (ISerializationContext ctx : constraint.getContexts()) {
Action action = ctx.getAssignedAction();
if (action != null) {
ParserRule rule = GrammarUtil.containingParserRule(action);
if (!contextRules.contains(rule) && relevantRules.contains(rule)) {
relevantActions.add(action);
}
}
}
List<String> actions = Lists.newArrayList();
List<String> rules = Lists.newArrayList();
Multimap<Parameter, Boolean> parameterValues = collectAllParameterValues(constraint);
for (Action a : relevantActions) actions.add(context2Name.getUniqueActionName(a));
for (ParserRule rule : relevantRules) {
StringBuilder segments = new StringBuilder();
for (Parameter param : rule.getParameters()) {
Collection<Boolean> values = parameterValues.get(param);
if (values.size() == 1) {
segments.append(param.getName() + "$" + values.iterator().next() + "$");
}
}
if (segments.length() == 0) {
rules.add(rule.getName());
} else {
rules.add(rule.getName() + "$" + segments);
}
}
Collections.sort(rules);
String result = Joiner.on("_").join(rules);
if (!actions.isEmpty()) {
Collections.sort(actions);
result += "_" + Joiner.on('_').join(actions);
}
return result;
}
Aggregations