package org.jactr.tools.analysis.production.endstates.impl; /* * default logging */ import java.util.ArrayList; 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.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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; /** * deal with add operations.. * * @author harrison */ public class AddEndStateComputer implements IBufferEndStateComputer { /** * Logger definition */ static private final transient Log LOGGER = LogFactory .getLog(AddEndStateComputer.class); public Collection<BufferEndState> computePossibleEndStatesFor( BufferEndStates endStates, String bufferName, SequenceAnalyzer analyzer) { String lowerBufferName = bufferName.toLowerCase(); Map<String, CommonTree> addActions = endStates .getMapOfTrees(JACTRBuilder.ADD_ACTION); /* * no add actions at all */ if (!addActions.containsKey(lowerBufferName)) return Collections.emptyList(); CommonTree addAction = addActions.get(lowerBufferName); Collection<CommonTree> mSlots = BufferStateUtilities .getAssignments(BufferStateUtilities.getSlots(addAction)); 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); } /* * lets check the content of the add, is it a variable, chunk or chuktype. * ADD_ACTION(bufferName content slots) */ CommonTree content = (CommonTree) addAction.getChild(1); int type = content.getType(); if (type == JACTRBuilder.CHUNK_TYPE_IDENTIFIER) { /* * if the add is a chunk pattern (chunk type is provided) we should add * any default slot values that have no already been overridden TODO add * default slot values from chunk type */ for (CommonTree slot : analyzer.getChunkTypeSlots(content.getText())) { String slotName = ASTSupport.getName(slot).toLowerCase(); if (!addedSlotNames.contains(slotName)) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Adding chunktype slot " + slot.toStringTree()); endState.addSlotHypothesis(slot); addedSlotNames.add(slotName); } } } else if (type == JACTRBuilder.CHUNK_IDENTIFIER) { if (LOGGER.isWarnEnabled()) LOGGER.warn(" currently ignoring adds of precise chunks"); } else if (type == JACTRBuilder.VARIABLE) { /* * a previously bound buffer.. */ String otherBuffer = content.getText().substring(1).toLowerCase(); Map<String, CommonTree> matches = endStates .getMapOfTrees(JACTRBuilder.MATCH_CONDITION); if (matches.containsKey(otherBuffer)) { Map<Integer, Collection<CommonTree>> allCSlots = BufferStateUtilities .getSlots(matches.get(otherBuffer)); Collection<CommonTree> cSlots = BufferStateUtilities .getNonVariables(allCSlots); /* * first grab all the conditions for non-variable slots */ 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, and might also correspond to a bound * variable */ 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()); } } } } else if (LOGGER.isWarnEnabled()) LOGGER.warn("No clue how to handle an add of " + content + " (" + type + ")"); ArrayList<BufferEndState> rtn = new ArrayList<BufferEndState>(); if (!endState.isEmpty()) rtn.add(endState); rtn.add(new SimpleBufferEndState(bufferName, "state", BufferEndState.FREE, BufferEndState.ERROR, BufferEndState.BUSY)); rtn.add(new SimpleBufferEndState(bufferName, "state", BufferEndState.BUSY, BufferEndState.FREE, BufferEndState.ERROR)); rtn.add(new SimpleBufferEndState(bufferName, "state", BufferEndState.ERROR, BufferEndState.BUSY, BufferEndState.FREE)); return rtn; } }