package org.jactr.tools.analysis.production.endstates.impl;
/*
* default logging
*/
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.antlr.runtime.tree.CommonTree;
import org.jactr.core.slot.IConditionalSlot;
import org.jactr.io.antlr3.builder.JACTRBuilder;
import org.jactr.io.antlr3.misc.ASTSupport;
import org.jactr.tools.analysis.production.SequenceAnalyzer;
import org.jactr.tools.analysis.production.endstates.BufferEndState;
import org.jactr.tools.analysis.production.endstates.BufferEndStates;
import org.jactr.tools.analysis.production.endstates.IBufferEndStateComputer;
/**
* computes the end state for a given buffer where the action is a modify and
* possibly a condition (well, there'd better be a condition).
*
* @author harrison
*/
public class ModifyEndStateComputer implements IBufferEndStateComputer
{
public Collection<BufferEndState> computePossibleEndStatesFor(
BufferEndStates endStates, String bufferName, SequenceAnalyzer analyzer)
{
String lowerBufferName = bufferName.toLowerCase();
CommonTree modify = endStates.getMapOfTrees(JACTRBuilder.MODIFY_ACTION)
.get(lowerBufferName);
if (modify == null) return Collections.emptyList();
CommonTree condition = endStates
.getMapOfTrees(JACTRBuilder.MATCH_CONDITION).get(lowerBufferName);
if (condition == null) return Collections.emptyList();
/*
* now we snag all the non variable slots
*/
Map<Integer, Collection<CommonTree>> allCSlots = BufferStateUtilities
.getSlots(condition);
Collection<CommonTree> cSlots = BufferStateUtilities
.getNonVariables(allCSlots);
Collection<CommonTree> mSlots = BufferStateUtilities
.getAssignments(BufferStateUtilities.getSlots(modify));
BufferEndState endState = new BufferEndState(bufferName);
/*
* we will add all the modified slots, and then all the conditional slots
* that weren't overwritten by the modified slots
*/
Set<String> addedSlotNames = new TreeSet<String>();
for (CommonTree mSlot : mSlots)
{
String name = ASTSupport.getName(mSlot);
addedSlotNames.add(name.toLowerCase());
if (BufferStateUtilities.contentIsType(mSlot, JACTRBuilder.VARIABLE))
{
for (CommonTree expanded : BufferStateUtilities.expandVariable(name,
BufferStateUtilities.getContent(mSlot), endStates))
endState.addSlotHypothesis(expanded);
}
else
endState.addSlotHypothesis(mSlot);
}
for (CommonTree cSlot : cSlots)
if (!addedSlotNames.contains(ASTSupport.getName(cSlot).toLowerCase()))
{
endState.addSlotHypothesis(cSlot);
addedSlotNames.add(ASTSupport.getName(cSlot).toLowerCase());
}
/*
* one last step. We ignored the variablized slots in the condition above.
* Now we need to go through them because any variable is actually the same
* as != null
*/
if (allCSlots.containsKey(JACTRBuilder.VARIABLE))
for (CommonTree cSlot : allCSlots.get(JACTRBuilder.VARIABLE))
{
String name = ASTSupport.getName(cSlot);
if (!addedSlotNames.contains(name.toLowerCase()))
{
for (CommonTree expanded : BufferStateUtilities.expandVariable(name,
BufferStateUtilities.getContent(cSlot), endStates))
endState.addSlotHypothesis(expanded);
addedSlotNames.add(name.toLowerCase());
}
}
if (endState.isEmpty()) return Collections.emptyList();
return Collections.singleton(endState);
}
}