Initial contribution of core script analysis code

git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@628 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
dolby-oss 2007-02-02 17:36:30 +00:00
parent 36bd8e5b23
commit 978000eff4
148 changed files with 12633 additions and 0 deletions

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,6 @@
#*
*#
*~
*.class
bin
build

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_BUILD_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#13;&#10;&lt;launchConfigurationWorkingSet editPageId=&quot;org.eclipse.ui.resourceWorkingSetPage&quot; factoryID=&quot;org.eclipse.ui.internal.WorkingSetFactory&quot; label=&quot;workingSet&quot; name=&quot;workingSet&quot;&gt;&#13;&#10;&lt;item factoryID=&quot;org.eclipse.ui.internal.model.ResourceFactory&quot; path=&quot;/com.ibm.capa.util.automaton/src/com/ibm/capa/util/automaton/parser/AmtParser.jy&quot; type=&quot;1&quot;/&gt;&#13;&#10;&lt;/launchConfigurationWorkingSet&gt;}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v &quot;${resource_loc}&quot;"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${project}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${container_loc}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${kmyacc}"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
</launchConfiguration>

38
com.ibm.wala.automaton/.project Executable file
View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.ibm.wala.automaton</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>auto,full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/KMYacc.launch</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,19 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Automaton Plug-in
Bundle-SymbolicName: com.ibm.capa.util.automaton
Bundle-Version: 1.0.0
Bundle-Activator: com.ibm.wala.automaton.AutomatonPlugin
Bundle-Vendor: IBM
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime
Eclipse-AutoStart: true
Export-Package: com.ibm.wala.automaton,
com.ibm.wala.automaton.grammar.string,
com.ibm.wala.automaton.grammar.tree,
com.ibm.wala.automaton.parser,
com.ibm.wala.automaton.regex.string,
com.ibm.wala.automaton.regex.tree,
com.ibm.wala.automaton.string,
com.ibm.wala.automaton.tree

View File

@ -0,0 +1,7 @@
* Rewrite all the method in a functional style.
* Adapt to Java5.
- Use generics for collections and grammars.
- Use the new "for" syntax. E.g.: for(Type elem : collection){...}
- Use the "assert".
- Use the auto-boxing/unboxing.

View File

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
=======================================================================
CAPA Util Automaton build file
=======================================================================
-->
<project name="com.ibm.capa.util.automaton" default="jar" basedir=".">
<!-- Software version details -->
<property name="name" value="capautilautomaton" />
<property name="module_name" value="com.ibm.capa.util.automaton" />
<property name="Name" value="CAPA Util Automaton" />
<property name="version" value="1-alpha" />
<!-- Compilation switches -->
<property name="debug" value="true" />
<property name="deprecation" value="false" />
<property name="optimize" value="true" />
<property name="javacFailOnError" value="true" />
<property name="javacDebugInfo" value="on" />
<property name="javacVerbose" value="false" />
<!-- Set global properties for this build -->
<property name="src" value="src" />
<property name="src.tests" value="tests" />
<property name="build" value="build" />
<property name="build.result" value="${basedir}" />
<property name="build.tests" value="${basedir}" />
<property name="build.javadocs" value="${build}/javadocs" />
<property name="publish.javadocs" value="javadocs/com.ibm.capa.util.automaton" />
<property name="dist" value="dist" />
<property name="etc" value="etc" />
<property name="docs" value="docs" />
<property name="lib" value="lib" />
<property name="mainlib" value="../mainlib" />
<property name="sharedlib" value="../sharedlib" />
<property name="cvsroot" value="/gsa/watgsa/home/d/o/dolby/cvs/CAstAnalysis"/>
<import file="${sharedlib}/scripts/common-targets.xml"/>
</project>

View File

@ -0,0 +1,268 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton;
import java.io.*;
import java.util.*;
public class AUtil {
static public Collection collection(Class klass, Object objs[]) throws InstantiationException, IllegalAccessException {
Collection c = (Collection) klass.newInstance();
for (int i = 0; i < objs.length; i++) {
c.add(objs[i]);
}
return c;
}
static public Collection collection(Class klass, Iterator iter) throws InstantiationException, IllegalAccessException {
Collection c = (Collection) klass.newInstance();
while (iter.hasNext()) {
c.add(iter.next());
}
return c;
}
static public List list(Object objs[]) {
try {
return (List) collection(ArrayList.class, objs);
} catch (InstantiationException e) {
e.printStackTrace();
return null;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
static public List list(Iterator i) {
try {
return (List) collection(ArrayList.class, i);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
static public Set set(Object objs[]) {
try {
return (Set) collection(HashSet.class, objs);
} catch (InstantiationException e) {
e.printStackTrace();
return null;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
static public Set set(Iterator i) {
try {
return (Set) collection(HashSet.class, i);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
static public Map map(Object keys[], Object vals[]) {
Map m = new HashMap();
for (int i = 0; i < keys.length; i++) {
if (i < vals.length) {
m.put(keys[i], vals[i]);
}
else {
m.put(keys[i], null);
}
}
return m;
}
static public Set allOrder(Set s) {
return allOrder(new ArrayList(s));
}
static public Set allOrder(List l) {
if (l.isEmpty()) {
return new HashSet();
}
else {
Object hd = l.get(0);
l.remove(0);
Set comb = insertAll(hd, allOrder(l));
return comb;
}
}
static private Set insert(Object o, List l) {
HashSet comb = new HashSet();
int size = l.size();
for (int i = 0; i <= size; i++) {
ArrayList cl = new ArrayList(l);
cl.add(i, o);
comb.add(cl);
}
return comb;
}
static private Set insertAll(Object o, Set s) {
HashSet comb = new HashSet();
if (s.isEmpty()) {
comb.addAll(insert(o, new ArrayList()));
}
else {
for (Iterator i = s.iterator(); i.hasNext(); ) {
List l = (List) i.next();
comb.addAll(insert(o, l));
}
}
return comb;
}
static public List sort(Collection collection) {
List l = new ArrayList(collection);
Collections.sort(l, new Comparator(){
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}});
return l;
}
public interface IElementMapper {
Object map(Object obj);
}
static public List collect(Collection collection, IElementMapper mapper) {
List result = new ArrayList();
for (Iterator i = collection.iterator(); i.hasNext(); ) {
Object obj = i.next();
obj = mapper.map(obj);
result.add(obj);
}
return result;
}
public interface IElementSelector {
boolean selected(Object obj);
}
static public List select(Collection collection, IElementSelector selector) {
List result = new ArrayList();
for (Iterator i = collection.iterator(); i.hasNext(); ) {
Object obj = i.next();
if (selector.selected(obj)) {
result.add(obj);
}
}
return result;
}
/**
* create an unique string that is not contained by names.
* @param prefix
* @param names an unique string is added
* @param start
* @return
*/
static public String createUniqueName(final String prefix, final Collection names, int start) {
int i = start;
String name = ((prefix==null) ? "n" : prefix) + Integer.toString(i);
while (names.contains(name)) {
i ++;
name = ((prefix==null) ? "n" : prefix) + Integer.toString(i);
}
names.add(name);
return name;
}
static public String createUniqueName(final String prefix, final Collection names) {
return createUniqueName(prefix, names, 1);
}
static public String lineSeparator = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
static public String prettyFormat(Object obj) {
return prettyFormat(obj, 4);
}
static public String prettyFormat(Object obj, int indent) {
return prettyFormat(obj, "", indent);
}
static public String prettyFormat(Object obj, String prefix, int indent) {
StringBuffer buff = new StringBuffer();
prettyFormat(obj.toString().toCharArray(), 0, buff, prefix, indent);
return buff.toString();
}
static public int prettyFormat(char cs[], int index, StringBuffer buff, String prefix, int indent) {
int i;
buff.append(prefix);
for (i = index; i < cs.length; i++) {
char c = cs[i];
switch (c) {
case '{':
buff.append(c);
buff.append(lineSeparator);
while(i+1<cs.length && Character.isSpaceChar(cs[i+1])){
i++;
}
String prefix2 = prefix;
for (int j=0; j<indent; j++){ prefix2 = prefix2 + " "; }
i = prettyFormat(cs, i+1, buff, prefix2, indent);
break;
case '}':
prefix = prefix.substring(0, prefix.length()-indent);
buff.append(lineSeparator + prefix);
while(i+1<cs.length && Character.isSpaceChar(cs[i+1])){
i++;
}
buff.append(c);
return i;
case ';':
case ',':
buff.append(c);
buff.append(lineSeparator + prefix);
while(i+1<cs.length && Character.isSpaceChar(cs[i+1])){
i++;
}
break;
case ' ':
case '\t':
buff.append(' ');
break;
default:
buff.append(c);
}
}
return i;
}
static public Object deepCopy(Object obj) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
return ois.readObject();
} catch (IOException e) {
throw(new RuntimeException(e));
} catch (ClassNotFoundException e) {
throw(new RuntimeException(e));
}
}
}

View File

@ -0,0 +1,64 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton;
import org.eclipse.ui.plugin.*;
import org.eclipse.jface.resource.ImageDescriptor;
import org.osgi.framework.BundleContext;
/**
* The main plugin class to be used in the desktop.
*/
public class AutomatonPlugin extends AbstractUIPlugin {
//The shared instance.
private static AutomatonPlugin plugin;
/**
* The constructor.
*/
public AutomatonPlugin() {
plugin = this;
}
/**
* This method is called upon plug-in activation
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/**
* This method is called when the plug-in is stopped
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
plugin = null;
}
/**
* Returns the shared instance.
*/
public static AutomatonPlugin getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path.
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return AbstractUIPlugin.imageDescriptorFromPlugin("com.ibm.capa.util.automaton", path);
}
}

View File

@ -0,0 +1,97 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class DMap<K,V> implements Map<K,V> {
public interface Factory<K,V> {
public V create(K key);
}
private HashMap<K,V> map;
private Factory<K,V> factory;
public DMap(Factory<K,V> factory) {
this.map = new HashMap<K,V>();
this.factory = factory;
}
public DMap(){
this(null);
}
protected V create(K key) {
return factory.create(key);
}
public int size() {
return map.size();
}
public void clear() {
map.clear();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean containsKey(Object key) {
return map.containsKey(key);
}
public boolean containsValue(Object value) {
return map.containsValue(value);
}
public Collection<V> values() {
return map.values();
}
public void putAll(Map<? extends K,? extends V> t) {
map.putAll(t);
}
public Set<Entry<K,V>> entrySet() {
return map.entrySet();
}
public Set<K> keySet() {
return map.keySet();
}
public V get(Object key) {
if (containsKey(key)) {
return map.get(key);
}
else {
V v = create((K)key);
map.put((K)key,v);
return v;
}
}
public V remove(Object key) {
return map.remove(key);
}
public V put(K key, V value) {
return map.put(key, value);
}
public String toString() {
return map.toString();
}
}

View File

@ -0,0 +1,66 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.string.*;
public abstract class AbstractGrammar<T extends IProductionRule> implements IGrammar<T> {
public void traverseSymbols(final ISymbolVisitor visitor) {
if (getStartSymbol() != null) {
getStartSymbol().traverse(visitor);
}
traverseRules(new IRuleVisitor(){
public void onVisit(IProductionRule rule) {
rule.traverseSymbols(visitor);
}
});
}
public void traverseRules(IRuleVisitor visitor) {
for (Iterator i = getRules().iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
rule.traverse(visitor);
}
}
public void traverse(IGrammarVisitor<T> visitor) {
visitor.onVisit(this);
traverseSymbols(visitor);
traverseRules(visitor);
}
public Set<IVariable> getNonterminals() {
// Set<IProductionRule> l = new ArrayList();
Set<IVariable> l = new HashSet<IVariable>();
l.add(getStartSymbol());
for (Iterator i = getRules().iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
l.add(rule.getLeft());
for (Iterator j = rule.getRight().iterator(); j.hasNext(); ) {
ISymbol s = (ISymbol) j.next();
if (s instanceof IVariable) {
l.add((IVariable)s);
}
}
}
return l;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw(new RuntimeException(e));
}
}
}

View File

@ -0,0 +1,36 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.Collection;
import java.util.Iterator;
import com.ibm.wala.automaton.string.*;
public abstract class AbstractRuleCopier implements IRuleCopier {
public abstract IProductionRule copy(IProductionRule rule);
public Collection copyRules(Collection rules) {
try {
Collection c = (Collection) rules.getClass().newInstance();
for (Iterator i = rules.iterator(); i.hasNext(); ) {
IProductionRule r = (IProductionRule) i.next();
c.add(r.copy(this));
}
return c;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw(new AssertionError("should not reach this code."));
}
}

View File

@ -0,0 +1,131 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.regex.string.StringPatternSymbol;
import com.ibm.wala.automaton.string.*;
public class CFGSymbol implements IGrammarSymbol<IContextFreeGrammar> {
private IContextFreeGrammar cfg;
public CFGSymbol(IContextFreeGrammar cfg) {
this.cfg = cfg;
}
public IContextFreeGrammar getGrammar() {
return cfg;
}
public String getName() {
return cfg.toString();
}
// TODO: improve CFGSymbol#matches()
public boolean matches(ISymbol symbol, IMatchContext context) {
if (symbol instanceof StringPatternSymbol) {
return false;
}
else if (symbol instanceof StringSymbol) {
StringSymbol ss = (StringSymbol) symbol;
return CFLReachability.containsSome(cfg, ss.toCharSymbols());
}
else if (symbol instanceof CFGSymbol) {
CFGSymbol cfgSym = (CFGSymbol) symbol;
if (cfg.equals(cfgSym.getGrammar())) {
context.put(this, symbol);
return true;
}
else {
return false;
}
}
else {
return false;
}
}
public boolean possiblyMatches(ISymbol symbol, IMatchContext context) {
if (symbol instanceof StringPatternSymbol) {
StringPatternSymbol sps = (StringPatternSymbol) symbol;
if (CFLReachability.containsSome(cfg, sps.getCompiledPattern())) {
return true;
}
IAutomaton fst = Grammars.toAutomaton(cfg);
if (CFLReachability.containsSome(Grammars.toCFG(sps.getCompiledPattern()), fst)) {
return true;
}
return false;
}
else if (symbol instanceof StringSymbol) {
StringSymbol ss = (StringSymbol) symbol;
return CFLReachability.containsSome(cfg, ss.toCharSymbols());
}
else if (symbol instanceof CFGSymbol) {
CFGSymbol cfg2 = (CFGSymbol) symbol;
IAutomaton fst2 = Grammars.toAutomaton(cfg2.getGrammar());
if (CFLReachability.containsSome(cfg, fst2)) {
return true;
}
IAutomaton fst = Grammars.toAutomaton(cfg);
if (CFLReachability.containsSome(cfg2.getGrammar(), fst)) {
return true;
}
return false;
}
else {
return false;
}
}
public int hashCode() {
return cfg.hashCode();
}
public boolean equals(Object obj) {
if (!getClass().equals(obj.getClass())) return false;
CFGSymbol cfgSym = (CFGSymbol) obj;
return cfg.equals(cfgSym.cfg);
}
public void traverse(ISymbolVisitor visitor) {
visitor.onVisit(this);
visitor.onLeave(this);
}
public ISymbol copy(ISymbolCopier copier) {
ISymbol s = copier.copy(this);
if (s instanceof CFGSymbol) {
CFGSymbol cfgSym = (CFGSymbol) s;
if (copier instanceof IGrammarCopier) {
IGrammarCopier gCopier = (IGrammarCopier) copier;
cfgSym.cfg = (IContextFreeGrammar) gCopier.copy(cfgSym.cfg);
}
}
return s;
}
public String toString() {
return "CFGSymbol(" + cfg.toString() + ")";
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw(new RuntimeException(e));
}
}
public int size() {
return 0;
}
}

View File

@ -0,0 +1,578 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.*;
import com.ibm.wala.automaton.string.*;
public class CFLReachability {
static public IAutomaton lastResult;
static public class AnalysisTransition extends Transition {
public AnalysisTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols) {
super(preState, postState, inputSymbol, outputSymbols);
}
public AnalysisTransition(IState preState, IState postState, ISymbol inputSymbol, ISymbol[] outputSymbols) {
super(preState, postState, inputSymbol, outputSymbols);
}
public boolean accept(ISymbol s, IMatchContext ctx) {
if (getInputSymbol().equals(s)) {
ctx.put(getInputSymbol(), s);
return true;
}
else {
return false;
}
}
}
static public class ProductionRuleTransition extends CFLReachability.AnalysisTransition {
private IProductionRule rule;
public ProductionRuleTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols,
IProductionRule rule) {
super(preState, postState, inputSymbol, outputSymbols);
this.rule = rule;
}
public ProductionRuleTransition(IState preState, IState postState, ISymbol inputSymbol, ISymbol outputSymbols[],
IProductionRule rule) {
super(preState, postState, inputSymbol, outputSymbols);
this.rule = rule;
}
public ProductionRuleTransition(ProductionRuleTransition transition) {
this(transition.getPreState(), transition.getPostState(),
transition.getInputSymbol(), AUtil.list(transition.getOutputSymbols()),
transition.getProductionRule());
}
public IProductionRule getProductionRule() {
return rule;
}
public int hashCode() {
return super.hashCode() + rule.hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (getClass().equals(obj.getClass())) {
ProductionRuleTransition trans = (ProductionRuleTransition) obj;
return super.equals(obj)
&& rule.equals(trans.getProductionRule());
}
else{
return false;
}
}
public String toString() {
return super.toString() + "#{rule:" + rule + "}";
}
}
static public interface ITransitionFactory {
AnalysisTransition createTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols, IProductionRule rule, List assocTransitions);
}
static abstract public class AbstractTransitionFactory implements ITransitionFactory {
abstract public AnalysisTransition createTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols, IProductionRule rule, List assocTransitions);
public AnalysisTransition createTransition(IState preState, IState postState, ISymbol inputSymbol, ISymbol outputSymbols[], IProductionRule rule, ITransition assocTransitions[]) {
return createTransition(preState, postState, inputSymbol, AUtil.list(outputSymbols), rule, AUtil.list(assocTransitions));
}
public AnalysisTransition createTransition(IState preState, IState postState, ISymbol inputSymbol, ISymbol outputSymbols[], IProductionRule rule, ITransition assocTransition) {
return createTransition(preState, postState, inputSymbol, outputSymbols, rule, new ITransition[]{assocTransition});
}
public AnalysisTransition createTransition(IState preState, IState postState, ISymbol inputSymbol, ISymbol outputSymbols[], IProductionRule rule, ITransition assocTransition1, ITransition assocTransition2) {
return createTransition(preState, postState, inputSymbol, outputSymbols, rule, new ITransition[]{assocTransition1, assocTransition2});
}
}
static public class SimpleTransitionFactory extends AbstractTransitionFactory {
public AnalysisTransition createTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols, IProductionRule rule, List assocTransitions) {
return new AnalysisTransition(preState, postState, inputSymbol, outputSymbols);
}
}
static public class ProductionRuleTransitionFactory extends CFLReachability.AbstractTransitionFactory {
public CFLReachability.AnalysisTransition createTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols, IProductionRule rule, List assocTransitions) {
return new ProductionRuleTransition(preState, postState, inputSymbol, outputSymbols, rule);
}
}
static public class TraceableTransitionFactory extends AbstractTransitionFactory {
private Set correspondings;
private ITransitionFactory factory;
public TraceableTransitionFactory(ITransitionFactory factory) {
this.correspondings = new HashSet();
this.factory = factory;
}
public AnalysisTransition createTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols, IProductionRule rule, List assocTransitions) {
AnalysisTransition t = factory.createTransition(preState, postState, inputSymbol, outputSymbols, rule, assocTransitions);
CorrespondingPath c = new CorrespondingPath(t, assocTransitions);
if (!correspondings.contains(c)) {
correspondings.add(c);
}
return t;
}
public Set getCorrespondingTransitions() {
return correspondings;
}
}
static public class CorrespondingPath {
public ITransition derivedTransition;
// public List<ITransition> path;
public List pathTransitions;
public CorrespondingPath(ITransition transition) {
derivedTransition = transition;
pathTransitions = new ArrayList();
}
public CorrespondingPath(ITransition transition, List paths) {
this(transition);
pathTransitions.addAll(paths);
}
public CorrespondingPath(ITransition transition, ITransition path1) {
this(transition);
pathTransitions.add(path1);
}
public CorrespondingPath(ITransition transition, ITransition path1, ITransition path2) {
this(transition, path1);
pathTransitions.add(path2);
}
public int hashCode() {
return derivedTransition.hashCode() + pathTransitions.hashCode();
}
public boolean equals(Object obj) {
if (!obj.getClass().equals(this.getClass())) return false;
CorrespondingPath path = (CorrespondingPath) obj;
return derivedTransition.equals(path.derivedTransition)
&& pathTransitions.equals(path.pathTransitions);
}
public String toString() {
return "{derived: " + derivedTransition + ", path: " + pathTransitions + "}";
}
}
static private boolean isSimplified(IContextFreeGrammar cfg) {
for (Iterator i = cfg.getRules().iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
int size = rule.getRight().size();
if (size > 2) {
return false;
}
}
return true;
}
static public IAutomaton analyze(IAutomaton automaton, IContextFreeGrammar cfg, ITransitionFactory factory){
IAutomaton result = (IAutomaton) automaton.copy(SimpleSTSCopier.defaultCopier);
Automatons.eliminateEpsilonTransitions(result);
Automatons.eliminateUnreachableStates(result);
if (!isSimplified(cfg)) {
cfg = (IContextFreeGrammar) cfg.copy(new DeepGrammarCopier(SimpleRuleCopier.defaultCopier));
Grammars.simplifyRules(cfg, null);
}
Set newTransitions = new HashSet();
do {
newTransitions.clear();
for (Iterator i = cfg.getRules().iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
addTransitionFor(result, rule, newTransitions, factory);
}
result.getTransitions().addAll(newTransitions);
} while(!newTransitions.isEmpty());
lastResult = result;
return result;
}
/**
* add a transition corresponding to a specified production
* rule to a normalized automaton.
* @param rule production rule
* @return returns true if a new transition is added.
*/
static private void addTransitionFor(IAutomaton result, IProductionRule rule, Set newTransitions, ITransitionFactory factory) {
if (rule.isEpsilonRule()) {
addTransitionForEpsilonRule(result, rule, newTransitions, factory);
}
else {
for (Iterator i = result.getTransitions().iterator(); i.hasNext(); ) {
ITransition trans = (ITransition) i.next();
addTransitionFor(result, trans, rule, newTransitions, factory);
}
}
}
private static void addTransitionForEpsilonRule(IAutomaton result, IProductionRule rule, Set newTransitions, ITransitionFactory factory) {
for (Iterator i = result.getStates().iterator(); i.hasNext(); ) {
IState state = (IState) i.next();
ITransition newTrans = factory.createTransition(state, state, rule.getLeft(), new ArrayList(), rule, new ArrayList());
if (!result.getTransitions().contains(newTrans)) {
newTransitions.add(newTrans);
}
}
}
private static void addTransitionFor(IAutomaton result, ITransition trans, IProductionRule rule, Set newTransitions, ITransitionFactory factory) {
ISymbol right0 = rule.getRight(0);
if (trans.accept(right0, new MatchContext())) {
// System.err.println(trans + " accept: " + rule.getRight(0) + "(" + trans.getClass() + ")");
if (rule.getRight().size() == 1) {
ArrayList output = new ArrayList();
if ((right0 instanceof IVariable) && isAlreadyAdded(trans.getPreState(), trans.getPostState(), (IVariable)right0, rule, result, newTransitions)){
output.add(right0);
}
else {
output.addAll(trans.transit(right0));
}
ArrayList assocTransitions = new ArrayList();
assocTransitions.add(trans);
ITransition newTrans = factory.createTransition(trans.getPreState(), trans.getPostState(), rule.getLeft(), output, rule, assocTransitions);
if (!result.getTransitions().contains(newTrans)) {
//System.out.println("rule=" + rule + ", trans=" + trans + ", newTrans=" + newTrans);
newTransitions.add(newTrans);
}
}
else { // size == 2
for (Iterator j = result.getAcceptTransitions(trans.getPostState(), rule.getRight(1)).iterator(); j.hasNext(); ) {
ISymbol right1 = rule.getRight(1);
ITransition trans2 = (ITransition) j.next();
// System.err.println(trans2 + " accept: " + right1 + "(" + trans2.getClass() + ")");
List output = new ArrayList();
if ((right0 instanceof IVariable) && isAlreadyAdded(trans.getPreState(), trans.getPostState(), (IVariable)right0, rule, result, newTransitions)) {
output.add(right0);
}
else {
output.addAll(trans.transit(right0));
}
if ((right1 instanceof IVariable) && isAlreadyAdded(trans2.getPreState(), trans2.getPostState(), (IVariable)right1, rule, result, newTransitions)) {
output.add(right1);
}
else {
output.addAll(trans2.transit(right1));
}
ArrayList assocTransitions = new ArrayList();
assocTransitions.add(trans);
assocTransitions.add(trans2);
ITransition newTrans = factory.createTransition(trans.getPreState(), trans2.getPostState(), rule.getLeft(), output, rule, assocTransitions);
if (!result.getTransitions().contains(newTrans)) {
//System.out.println("rule=" + rule + ", trans=" + trans + ", trans2=" + trans2 + ", newTrans=" + newTrans);
newTransitions.add(newTrans);
}
}
}
}
}
static private boolean isAlreadyAdded(IState preState, IState postState, IVariable v, IProductionRule rule, IAutomaton automaton, Set newTransitions) {
for (Iterator i = automaton.getTransitions().iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
if (t.getPreState().equals(preState)
&& t.getPostState().equals(postState)
&& t.getInputSymbol().equals(v)) {
if (t instanceof ProductionRuleTransition) {
if (((ProductionRuleTransition) t).getProductionRule().equals(rule)) {
return true;
}
}
else {
return true;
}
}
}
for (Iterator i = newTransitions.iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
if (t.getPreState().equals(preState)
&& t.getPostState().equals(postState)
&& t.getInputSymbol().equals(v)) {
if (t instanceof ProductionRuleTransition) {
if (((ProductionRuleTransition) t).getProductionRule().equals(rule)) {
return true;
}
}
else {
return true;
}
}
}
return false;
}
static public Set getCorrespondingTransitions(IAutomaton automaton, IContextFreeGrammar cfg) {
return getCorrespondingTransitions(automaton, cfg.getRules());
}
static public Set getCorrespondingTransitions(IAutomaton automaton, IProductionRule rules[]) {
return getCorrespondingTransitions(automaton, AUtil.set(rules));
}
static public Set getCorrespondingTransitions(IAutomaton automaton, IProductionRule rule) {
return getCorrespondingTransitions(automaton, new IProductionRule[]{rule});
}
/**
* TODO: use ProductionRuleTransition#getProductionRule().
* @param automaton
* @param rules
* @return
*/
static public Set getCorrespondingTransitions(IAutomaton automaton, Collection rules) {
Map ruleMap = new HashMap();
Set transitions = new HashSet();
for (Iterator i = rules.iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
List l = (List) ruleMap.get(rule.getLeft());
if (l == null) {
l = new ArrayList();
ruleMap.put(rule.getLeft(), l);
}
l.add(rule);
}
for (Iterator i = automaton.getTransitions().iterator(); i.hasNext(); ) {
ITransition trans = (ITransition) i.next();
ISymbol isym = trans.getInputSymbol();
if ((isym instanceof IVariable) && ruleMap.containsKey(isym)) {
List l = (List) ruleMap.get(isym);
for (Iterator j = l.iterator(); j.hasNext(); ) {
IProductionRule rule = (IProductionRule) j.next();
if (rule.getRight().size() == 0) {
if (trans.getPreState().equals(trans.getPostState())) {
transitions.add(new CorrespondingPath(trans));
}
}
else if(rule.getRight().size() == 1) {
ISymbol sym1 = rule.getRight(0);
Set paths = getCorrespondingPath(automaton, trans, sym1);
if (!paths.isEmpty()) {
transitions.addAll(paths);
}
}
else {
ISymbol sym1 = rule.getRight(0);
ISymbol sym2 = rule.getRight(1);
Set paths = getCorrespondingPath(automaton, trans, sym1, sym2);
if (!paths.isEmpty()) {
transitions.addAll(paths);
}
}
}
}
}
return transitions;
}
static private Set getCorrespondingPath(IAutomaton automaton, ITransition derived, ISymbol input) {
return getCorrespondingPath(automaton, derived, derived.getPreState(), derived.getPostState(), input);
}
static private Set getCorrespondingPath(IAutomaton automaton, ITransition derived, ISymbol input1, ISymbol input2) {
return getCorrespondingPath(automaton, derived, derived.getPreState(), derived.getPostState(), input1, input2);
}
static private Set getCorrespondingPath(IAutomaton automaton, ITransition derived, IState preState, IState postState, ISymbol input) {
Set transitions = new HashSet();
for (Iterator i = automaton.getTransitions().iterator(); i.hasNext(); ) {
ITransition trans = (ITransition) i.next();
if (trans.getPreState().equals(preState)
&& trans.getPostState().equals(postState)
&& trans.getInputSymbol().equals(input)) {
transitions.add(new CorrespondingPath(derived, trans));
}
}
return transitions;
}
static private Set getCorrespondingPath(IAutomaton automaton, ITransition derived, IState preState, IState postState, ISymbol input1, ISymbol input2) {
Set transitions = new HashSet();
for (Iterator i = automaton.getTransitions(preState, input1).iterator(); i.hasNext(); ) {
ITransition trans1 = (ITransition) i.next();
for (Iterator j = getCorrespondingPath(automaton, derived, trans1.getPostState(), postState, input2).iterator(); j.hasNext(); ) {
CorrespondingPath path = (CorrespondingPath) j.next();
path.pathTransitions.add(0, trans1);
transitions.add(path);
}
}
return transitions;
}
static public boolean isReachable(IAutomaton automaton, IContextFreeGrammar cfg, Set nonterminals) {
IAutomaton result = analyze(automaton, cfg, new SimpleTransitionFactory());
IState initState = result.getInitialState();
Set finalStates = result.getFinalStates();
for (Iterator i = result.getTransitions().iterator(); i.hasNext(); ) {
ITransition trans = (ITransition) i.next();
if (initState.equals(trans.getPreState())
&& finalStates.contains(trans.getPostState())
&& nonterminals.contains(trans.getInputSymbol())) {
return true;
}
}
return false;
}
static public boolean isReachable(IAutomaton automaton, IContextFreeGrammar cfg, IVariable nonterminals[]) {
return isReachable(automaton, cfg, AUtil.set(nonterminals));
}
static public boolean isReachable(IAutomaton automaton, IContextFreeGrammar cfg) {
return isReachable(automaton, cfg, new IVariable[]{cfg.getStartSymbol()});
}
static public Set selectConnectedCorrespondingTransitions(Set correspondings, IState preState, Collection postStates, ISymbol symbol) {
Set result = new HashSet();
for (Iterator i = correspondings.iterator(); i.hasNext(); ) {
CorrespondingPath path = (CorrespondingPath) i.next();
if (path.derivedTransition.getInputSymbol().equals(symbol)
&& path.derivedTransition.getPreState().equals(preState)
&& postStates.contains(path.derivedTransition.getPostState())) {
selectConnectedCorrespondingTransitions(correspondings, path.derivedTransition, result);
}
}
return result;
}
static public Set selectConnectedCorrespondingTransitions(Set correspondings, IState preState, IState postStates[], ISymbol symbol) {
return selectConnectedCorrespondingTransitions(correspondings, preState, AUtil.set(postStates), symbol);
}
static public Set selectConnectedCorrespondingTransitions(Set correspondings, CorrespondingPath path) {
Set s = new HashSet();
selectConnectedCorrespondingTransitions(correspondings, path, s);
return s;
}
static public Set selectConnectedCorrespondingTransitions(Set correspondings, ITransition transition) {
Set s = new HashSet();
selectConnectedCorrespondingTransitions(correspondings, transition, s);
return s;
}
static private void selectConnectedCorrespondingTransitions(Set correspondings, CorrespondingPath path, Set result) {
if (result.contains(path)) return;
if (!correspondings.contains(path)) return;
result.add(path);
for (Iterator i = path.pathTransitions.iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
selectConnectedCorrespondingTransitions(correspondings, t, result);
}
}
static private void selectConnectedCorrespondingTransitions(Set correspondings, ITransition transition, Set result) {
for (Iterator i = correspondings.iterator(); i.hasNext(); ) {
CorrespondingPath path = (CorrespondingPath) i.next();
if (path.derivedTransition.equals(transition)) {
selectConnectedCorrespondingTransitions(correspondings, path, result);
}
}
}
static public Set collectDerivedTransitions(Set correspondings) {
Set transitions = new HashSet();
for (Iterator i = correspondings.iterator(); i.hasNext(); ) {
CorrespondingPath p = (CorrespondingPath) i.next();
transitions.add(p.derivedTransition);
}
return transitions;
}
static public Set collectConnectedTransitions(Set correspondings) {
Set transitions = new HashSet();
for (Iterator i = correspondings.iterator(); i.hasNext(); ) {
CorrespondingPath p = (CorrespondingPath) i.next();
transitions.add(p.derivedTransition);
transitions.addAll(p.pathTransitions);
}
return transitions;
}
static public Set selectConnectedTransitions(IAutomaton automaton, IContextFreeGrammar cfg, IState preState, Collection postStates, ISymbol startSymbol) {
Set correspondings = getCorrespondingTransitions(automaton, cfg);
return selectConnectedTransitions(correspondings, preState, postStates, startSymbol);
}
static public Set selectConnectedTransitions(IAutomaton automaton, IContextFreeGrammar cfg, IState preState, IState postStates[], ISymbol startSymbol) {
Set correspondings = getCorrespondingTransitions(automaton, cfg);
return selectConnectedTransitions(correspondings, preState, postStates, startSymbol);
}
static public Set selectConnectedTransitions(Set correspondings, IState preState, Collection postStates, ISymbol symbol) {
Set s = selectConnectedCorrespondingTransitions(correspondings, preState, postStates, symbol);
return collectConnectedTransitions(s);
}
static public Set selectConnectedTransitions(Set correspondings, IState preState, IState postStates[], ISymbol symbol) {
Set s = selectConnectedCorrespondingTransitions(correspondings, preState, postStates, symbol);
return collectConnectedTransitions(s);
}
static public Set selectConnectedTransitions(Set correspondings, ITransition transition) {
Set s = selectConnectedCorrespondingTransitions(correspondings, transition);
return collectConnectedTransitions(s);
}
static public boolean containsSome(IContextFreeGrammar cfg, IAutomaton automaton) {
return isReachable(automaton, cfg);
}
static public boolean containsSome(IContextFreeGrammar cfg, ISymbol symbols[]) {
Automaton automaton = Automatons.createAutomaton(symbols);
return containsSome(cfg, automaton);
}
static public boolean containsSome(IContextFreeGrammar cfg, List symbols) {
ISymbol ary[] = new ISymbol[symbols.size()];
symbols.toArray(ary);
return containsSome(cfg, ary);
}
static public boolean notContainsAll(IContextFreeGrammar cfg, IAutomaton automaton) {
return !isReachable(automaton, cfg);
}
static public boolean notContainsAll(IContextFreeGrammar cfg, ISymbol symbols[]) {
Automaton automaton = Automatons.createAutomaton(symbols);
return notContainsAll(cfg, automaton);
}
static public boolean notContainsAll(IContextFreeGrammar cfg, List symbols) {
ISymbol ary[] = new ISymbol[symbols.size()];
symbols.toArray(ary);
return notContainsAll(cfg, ary);
}
static public boolean containsAll(IAutomaton automaton, IContextFreeGrammar cfg) {
return !isReachable(Automatons.createComplement(automaton, Grammars.collectTerminals(cfg)), cfg);
}
static public boolean containsAll(ISymbol symbols[], IContextFreeGrammar cfg) {
Automaton automaton = Automatons.createAutomaton(symbols);
return containsAll(automaton, cfg);
}
static public boolean containsAll(List symbols, IContextFreeGrammar cfg) {
ISymbol ary[] = new ISymbol[symbols.size()];
symbols.toArray(ary);
return containsAll(ary, cfg);
}
}

View File

@ -0,0 +1,56 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.AUtil;
import com.ibm.wala.automaton.string.*;
public class CFLTranslator {
private IAutomaton transducer;
private IAutomaton lastResult;
public CFLTranslator(IAutomaton transducer) {
this.transducer = transducer;
}
public IContextFreeGrammar translate(IContextFreeGrammar cfg) {
CFLReachability.TraceableTransitionFactory factory
= new CFLReachability.TraceableTransitionFactory(
new CFLReachability.ProductionRuleTransitionFactory());
lastResult = CFLReachability.analyze(transducer, cfg, factory);
Set paths = factory.getCorrespondingTransitions();
Set transitions = CFLReachability.selectConnectedTransitions(paths, transducer.getInitialState(), transducer.getFinalStates(), cfg.getStartSymbol());
Set rules = new HashSet();
for (Iterator i = transitions.iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
if ((t instanceof CFLReachability.ProductionRuleTransition) /* && (t.getInputSymbol() instanceof IVariable) */) {
IProductionRule rule = new ProductionRule((IVariable)t.getInputSymbol(), AUtil.list(t.getOutputSymbols()));
rules.add(rule);
}
}
if (rules.isEmpty()) {
IProductionRule rule = new ProductionRule(cfg.getStartSymbol(), new ISymbol[0]);
rules.add(rule);
}
IContextFreeGrammar cfg2 = new ContextFreeGrammar(cfg.getStartSymbol(), rules);
return cfg2;
}
static public IContextFreeGrammar translate(IAutomaton transducer, IContextFreeGrammar cfg) {
return (new CFLTranslator(transducer)).translate(cfg);
}
public IAutomaton getLastResult() {
return lastResult;
}
}

View File

@ -0,0 +1,33 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.string.*;
public class ContextFreeGrammar<T extends IProductionRule> extends SimpleGrammar<T> implements IContextFreeGrammar<T> {
public ContextFreeGrammar(){
super();
}
public ContextFreeGrammar(IVariable startSymbol, Collection<T> rules){
super(startSymbol, rules);
}
public ContextFreeGrammar(IVariable startSymbol, T rules[]){
super(startSymbol, rules);
}
public ContextFreeGrammar(SimpleGrammar<T> g) {
super(g);
}
}

View File

@ -0,0 +1,55 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.Collection;
import com.ibm.wala.automaton.string.ISymbol;
public class DeepGrammarCopier implements IGrammarCopier {
private IRuleCopier ruleCopier;
public DeepGrammarCopier(IRuleCopier ruleCopier) {
this.ruleCopier = ruleCopier;
}
public IGrammar copy(IGrammar grammar) {
return (IGrammar) grammar.clone();
}
public IProductionRule copy(IProductionRule rule) {
return ruleCopier.copy(rule);
}
public Collection copyRules(Collection rules) {
return ruleCopier.copyRules(rules);
}
public ISymbol copy(ISymbol symbol) {
return ruleCopier.copy(symbol);
}
public Collection copySymbols(Collection symbols) {
return ruleCopier.copySymbols(symbols);
}
public String copyName(String name) {
return ruleCopier.copyName(name);
}
public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol) {
return ruleCopier.copySymbolReference(parent, symbol);
}
public Collection copySymbolReferences(ISymbol parent, Collection symbols) {
return ruleCopier.copySymbolReferences(parent, symbols);
}
}

View File

@ -0,0 +1,47 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.string.*;
public class DeepRuleCopier extends AbstractRuleCopier {
private ISymbolCopier symbolCopier;
public DeepRuleCopier(ISymbolCopier symbolCopier) {
this.symbolCopier = symbolCopier;
}
public IProductionRule copy(IProductionRule rule) {
return (IProductionRule) rule.clone();
}
public ISymbol copy(ISymbol symbol) {
return symbolCopier.copy(symbol);
}
public Collection copySymbols(Collection symbols) {
return symbolCopier.copySymbols(symbols);
}
public String copyName(String name) {
return symbolCopier.copyName(name);
}
public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol) {
return symbolCopier.copySymbolReference(parent, symbol);
}
public Collection copySymbolReferences(ISymbol parent, Collection symbols) {
return symbolCopier.copySymbolReferences(parent, symbols);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.string.IVariable;
public interface IContextFreeGrammar<T extends IProductionRule> extends IGrammar<T>, ISimplify {
public void setStartSymbol(IVariable symbol);
public void addRule(T rule);
public void addRules(Collection<T> rules);
public void addRules(Iterator<T> rules);
}

View File

@ -0,0 +1,32 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.string.*;
public interface IGrammar<T extends IProductionRule> extends Cloneable {
public IVariable getStartSymbol();
public Set<IVariable> getNonterminals();
// public Set<IProductionRule> getRules();
public Set<T> getRules();
public Set<T> getRules(IVariable v);
public void traverseRules(IRuleVisitor visitor);
public void traverseSymbols(ISymbolVisitor visitor);
public void traverse(IGrammarVisitor<T> visitor);
public IGrammar copy(IGrammarCopier<T> copier);
public Object clone();
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
public interface IGrammarCopier<T extends IProductionRule> extends IRuleCopier {
IGrammar<T> copy(IGrammar<T> grammar);
}

View File

@ -0,0 +1,17 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import com.ibm.wala.automaton.string.*;
public interface IGrammarSymbol<T extends IGrammar> extends ISymbol {
T getGrammar();
}

View File

@ -0,0 +1,17 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import com.ibm.wala.automaton.string.ISymbolVisitor;
public interface IGrammarVisitor<T extends IProductionRule> extends ISymbolVisitor, IRuleVisitor {
public void onVisit(IGrammar<T> g);
}

View File

@ -0,0 +1,34 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.string.*;
public interface IProductionRule extends Cloneable {
public IVariable getLeft();
public void setLeft(IVariable left);
// public List<ISymbol> getRight();
public List getRight();
public ISymbol getRight(int index);
public boolean isEpsilonRule(); // = getRight().isEmpty()
public void traverseSymbols(ISymbolVisitor visitor);
public void traverse(IRuleVisitor visitor);
public IProductionRule copy(IRuleCopier copier);
public Object clone();
}

View File

@ -0,0 +1,20 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.Collection;
import com.ibm.wala.automaton.string.ISymbolCopier;
public interface IRuleCopier extends ISymbolCopier {
public IProductionRule copy(IProductionRule rule);
public Collection copyRules(Collection rules);
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
public interface IRuleVisitor {
void onVisit(IProductionRule rule);
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
public interface ISimplify {
SimpleGrammar toSimple();
}

View File

@ -0,0 +1,140 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.ibm.wala.automaton.string.ISymbol;
import com.ibm.wala.automaton.string.ISymbolVisitor;
import com.ibm.wala.automaton.string.IVariable;
public class ProductionRule implements IProductionRule {
private IVariable left;
private List sequence;
public ProductionRule(IVariable left, List sequence) {
init(left, sequence);
}
public ProductionRule(IVariable left, ISymbol sequence[]) {
List l = new ArrayList();
for (int i = 0; i < sequence.length; i++) {
l.add(sequence[i]);
}
init(left, l);
}
public ProductionRule(IVariable left, ISymbol right) {
this(left, new ISymbol[]{right});
}
public ProductionRule(IProductionRule rule){
init(rule.getLeft(), rule.getRight());
}
private void init(IVariable left, List sequence){
this.left = left;
this.sequence = new ArrayList();
addRight(sequence);
}
private void addRight(List sequence) {
for (Iterator i = sequence.iterator(); i.hasNext(); ) {
addRight((ISymbol)i.next());
}
}
private void addRight(ISymbol symbol) {
this.sequence.add(symbol);
}
public IVariable getLeft() {
return left;
}
public void setLeft(IVariable left) {
this.left = left;
}
public List getRight() {
return sequence;
}
public ISymbol getRight(int index) {
return (ISymbol) sequence.get(index);
}
public void traverseSymbols(ISymbolVisitor visitor) {
left.traverse(visitor);
for (Iterator i = sequence.iterator(); i.hasNext(); ) {
ISymbol s = (ISymbol) i.next();
s.traverse(visitor);
}
}
public void traverse(IRuleVisitor visitor) {
visitor.onVisit(this);
}
public boolean isEpsilonRule(){
return sequence.isEmpty();
}
public int hashCode(){
return 0;
/*
return left.hashCode() + sequence.hashCode();
*/
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
ProductionRule rule = (ProductionRule) obj;
return left.equals(rule.left)
&& sequence.equals(rule.sequence);
}
public String toString(){
StringBuffer buff = new StringBuffer();
buff.append("[");
for (Iterator i = getRight().iterator(); i.hasNext(); ) {
ISymbol symbol = (ISymbol) i.next();
buff.append(symbol);
if (i.hasNext()) {
buff.append(", ");
}
}
buff.append("]");
return left.toString() + " -> " + buff.toString();
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw(new RuntimeException(e));
}
}
public IProductionRule copy(IRuleCopier copier) {
IProductionRule rule = copier.copy(this);
if (rule instanceof ProductionRule) {
ProductionRule prule = (ProductionRule) rule;
prule.left = (IVariable) copier.copy(prule.left);
prule.sequence = new ArrayList(copier.copySymbols(prule.sequence));
}
return rule;
}
}

View File

@ -0,0 +1,138 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.*;
import com.ibm.wala.automaton.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.IBinaryTreeVariable;
public class SimpleGrammar<T extends IProductionRule> extends AbstractGrammar<T> implements ISimplify {
// private Set<IProductionRule> rules;
private Set<T> rules;
private IVariable startSymbol;
public SimpleGrammar(){
rules = new HashSet<T>();
startSymbol = null;
}
public SimpleGrammar(IVariable startSymbol, Collection<T> rules){
this();
setStartSymbol(startSymbol);
addRules(rules);
}
public SimpleGrammar(IVariable startSymbol, T rules[]){
this();
List<T> l = new ArrayList<T>();
for (int i = 0; i < rules.length; i++ ) {
l.add(rules[i]);
}
setStartSymbol(startSymbol);
addRules(l);
}
public SimpleGrammar(SimpleGrammar<T> g) {
this(g.getStartSymbol(), g.getRules());
}
public IVariable getStartSymbol() {
return startSymbol;
}
public void setStartSymbol(IVariable startSymbol){
this.startSymbol = startSymbol;
}
public Set<T> getRules() {
return rules;
}
public Set<T> getRules(IVariable v) {
return Grammars.getRules(this, v);
}
public void addRule(T rule) {
rules.add(rule);
}
public void addRules(Collection<T> rules) {
addRules(rules.iterator());
}
public void addRules(Iterator<T> rules) {
while (rules.hasNext()) {
addRule(rules.next());
}
}
public IGrammar copy(IGrammarCopier<T> copier) {
IGrammar g = copier.copy(this);
if (g instanceof SimpleGrammar) {
SimpleGrammar<IProductionRule> cfg = (SimpleGrammar<IProductionRule>) g;
cfg.rules = new HashSet<IProductionRule>(copier.copyRules(cfg.rules));
cfg.startSymbol = (IVariable) copier.copy(cfg.startSymbol);
}
return g;
}
public int hashCode() {
return getClass().hashCode();
/*
return rules.hashCode() + startSymbol.hashCode();
*/
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
SimpleGrammar cfg = (SimpleGrammar) obj;
/*
* TODO: why do we need this code?
*/
HashSet<T> s = new HashSet<T>(rules);
rules.clear();
rules.addAll(s);
return startSymbol.equals(cfg.getStartSymbol())
&& rules.equals(cfg.getRules());
}
public String toString() {
StringBuffer rulesStr = new StringBuffer();
List rules = new ArrayList();
for (Iterator i = AUtil.sort(getRules()).iterator(); i.hasNext(); ){
IProductionRule rule = (IProductionRule) i.next();
rules.add(rule);
}
Collections.sort(rules, new Comparator(){
public int compare(Object o1, Object o2) {
IProductionRule r1 = (IProductionRule) o1;
IProductionRule r2 = (IProductionRule) o2;
return r1.getLeft().getName().compareTo(r2.getLeft().getName());
}
});
for (Iterator i = rules.iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
rulesStr.append(rule.toString());
if (i.hasNext()) {
rulesStr.append("; ");
}
}
return "{start:" + getStartSymbol() + ", rules:{" + rulesStr + "}}";
}
public SimpleGrammar<T> toSimple() {
return this;
}
}

View File

@ -0,0 +1,52 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.Collection;
import com.ibm.wala.automaton.AUtil;
import com.ibm.wala.automaton.string.ISymbol;
public class SimpleGrammarCopier implements IGrammarCopier {
public IGrammar copy(IGrammar grammar) {
return (IGrammar) grammar.clone();
}
public IProductionRule copy(IProductionRule rule) {
return rule;
}
public Collection copyRules(Collection rules) {
return rules;
}
public ISymbol copy(ISymbol symbol) {
return symbol;
}
public Collection copySymbols(Collection symbols) {
return symbols;
}
public String copyName(String name) {
return name;
}
public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol) {
return symbol;
}
public Collection copySymbolReferences(ISymbol parent, Collection symbols) {
return symbols;
}
static final public SimpleGrammarCopier defaultCopier = new SimpleGrammarCopier();
}

View File

@ -0,0 +1,43 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.string;
import java.util.Collection;
import com.ibm.wala.automaton.string.ISymbol;
public class SimpleRuleCopier extends AbstractRuleCopier implements IRuleCopier {
public IProductionRule copy(IProductionRule rule) {
return (IProductionRule) rule.clone();
}
public ISymbol copy(ISymbol symbol) {
return symbol;
}
public Collection copySymbols(Collection symbols) {
return symbols;
}
public String copyName(String name) {
return name;
}
public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol) {
return symbol;
}
public Collection copySymbolReferences(ISymbol parent, Collection symbols) {
return symbols;
}
static public SimpleRuleCopier defaultCopier = new SimpleRuleCopier();
}

View File

@ -0,0 +1,18 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
import java.util.Comparator;
public interface IRTLComparator extends Comparator {
// for checking g1 contains g2
public boolean contains(ITreeGrammar g1, ITreeGrammar t2);
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
public interface IRTLTranslator {
public ITreeGrammar translate(ITreeGrammar g);
}

View File

@ -0,0 +1,18 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.string.IVariable;
public interface ITreeGrammar extends IGrammar, ISimplify {
public void setStartSymbol(IVariable symbol);
}

View File

@ -0,0 +1,100 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.regex.string.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.*;
public class RTGSymbol implements IBinaryTree {
private ITreeGrammar tg;
public RTGSymbol(ITreeGrammar tg) {
this.tg = tg;
}
public ITreeGrammar getTreeGrammar() {
return tg;
}
public String getName() {
return tg.toString();
}
public boolean matches(ISymbol symbol, IMatchContext context) {
if (symbol instanceof RTGSymbol) {
ITreeGrammar tg2 = ((RTGSymbol) symbol).getTreeGrammar();
return RTLComparator.defaultComparator.contains(tg, tg2);
}
else if (symbol instanceof IBinaryTree) {
BinaryTreeVariable v = new BinaryTreeVariable("G");
ITreeGrammar tg2 = new TreeGrammar(v, new ProductionRule[]{
new ProductionRule(v, symbol),
});
return RTLComparator.defaultComparator.contains(tg, tg2);
}
else {
return false;
}
}
public boolean possiblyMatches(ISymbol symbol, IMatchContext context) {
return matches(symbol, context) || symbol.matches(this, context);
}
public int hashCode() {
return tg.hashCode();
}
public boolean equals(Object obj) {
if (!getClass().equals(obj.getClass())) return false;
RTGSymbol tgSym = (RTGSymbol) obj;
return tg.equals(tgSym.tg);
}
public void traverse(ISymbolVisitor visitor) {
visitor.onVisit(this);
visitor.onLeave(this);
}
public ISymbol copy(ISymbolCopier copier) {
ISymbol s = copier.copy(this);
if (s instanceof RTGSymbol) {
RTGSymbol tgSym = (RTGSymbol) s;
if (copier instanceof IGrammarCopier) {
IGrammarCopier gCopier = (IGrammarCopier) copier;
tgSym.tg = (ITreeGrammar) gCopier.copy(tgSym.tg);
}
}
return s;
}
public String toString() {
return "RTGSymbol(" + tg.toString() + ")";
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw(new RuntimeException(e));
}
}
public int size() {
return 0;
}
public ISymbol getLabel() {
return tg.getStartSymbol();
}
}

View File

@ -0,0 +1,82 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
import java.util.*;
import com.ibm.wala.automaton.*;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.*;
public abstract class RTLAbstractTranslator implements IRTLTranslator {
private IStateTransitionSystem system;
static protected class StateVariable2Name extends DMap {
private Set names;
public StateVariable2Name(Set names) {
super();
this.names = new HashSet(names);
}
public StateVariable2Name(IGrammar g) {
this(Grammars.collectVariableNames(TreeGrammars.collectUsedVariables(g)));
}
public String get(StateBinaryTree t) {
return (String) super.get(t);
}
public String get(IState state, IBinaryTreeVariable v) {
return get(new StateBinaryTree(state, v));
}
public Object create(Object key) {
String vname = AUtil.createUniqueName("N", names);
return vname;
}
}
protected RTLAbstractTranslator(IStateTransitionSystem system) {
this.system = system;
}
public IStateTransitionSystem getSystem() {
return system;
}
protected Set translate(IBinaryTreeVariable v, IBinaryTree bt, final StateVariable2Name sv2name) {
Set transitions = system.getAcceptTransitions(TreeTransition.createCompositeState(bt), bt);
Set rules = new HashSet();
for (Iterator i = transitions.iterator(); i.hasNext(); ) {
ITreeTransition tr = (ITreeTransition) i.next();
IBinaryTree bt2 = tr.transit(bt);
IProductionRule rule = new ProductionRule(v, bt2);
rules.add(rule);
}
return rules;
}
protected Set getPrimitiveStates() {
Set states = new HashSet();
for (Iterator i = system.getStates().iterator(); i.hasNext(); ) {
IState s = (IState) i.next();
if (s instanceof CompositeState) {
CompositeState cs = (CompositeState) s;
states.addAll(AUtil.set(cs.getStates()));
}
else {
states.add(s);
}
}
return states;
}
}

View File

@ -0,0 +1,84 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
import java.util.*;
import com.ibm.wala.automaton.AUtil;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.*;
public class RTLBottomUpTranslator extends RTLAbstractTranslator {
public RTLBottomUpTranslator(BottomUpTreeAutomaton automaton) {
super(automaton);
}
public ITreeGrammar translate(ITreeGrammar g) {
g = (ITreeGrammar) g.copy(SimpleGrammarCopier.defaultCopier);
TreeGrammars.normalize(g);
//System.err.println(AUtil.prettyFormat(g));
Set rules = new HashSet();
StateVariable2Name sv2name = new StateVariable2Name(g);
Set pstates = getPrimitiveStates();
for (Iterator i = pstates.iterator(); i.hasNext(); ) {
IState lstate = (IState) i.next();
for (Iterator j = pstates.iterator(); j.hasNext(); ) {
IState rstate = (IState) j.next();
//System.err.println("state: " + lstate + ", " + rstate);
for (Iterator k = g.getRules().iterator(); k.hasNext(); ) {
IProductionRule rule = (IProductionRule) k.next();
IBinaryTree bt = (IBinaryTree) rule.getRight(0);
if (bt instanceof IParentBinaryTree) {
IParentBinaryTree pbt = (IParentBinaryTree) bt;
StateBinaryTree lbt = new StateBinaryTree(lstate, new BinaryTreeVariable(sv2name.get(lstate, (IBinaryTreeVariable)pbt.getLeft())));
StateBinaryTree rbt = new StateBinaryTree(rstate, new BinaryTreeVariable(sv2name.get(rstate, (IBinaryTreeVariable)pbt.getLeft())));
bt = new BinaryTree(bt.getLabel(), lbt, rbt);
}
//System.err.println(rule + " : " + rule.getLeft() + " -> " + bt);
Set rs = translate((IBinaryTreeVariable)rule.getLeft(), bt, sv2name);
Set rs2 = new HashSet();
//System.err.println(" " + rs);
for (Iterator l = rs.iterator(); l.hasNext(); ) {
IProductionRule r = (IProductionRule) l.next();
StateBinaryTree sv = (StateBinaryTree) r.getRight(0);
StateBinaryTree sv2 = new StateBinaryTree(sv.getState(), (IBinaryTreeVariable)rule.getLeft());
String vname = sv2name.get(sv2);
if (vname == null) throw(new AssertionError("should not be null."));
IBinaryTreeVariable v = new BinaryTreeVariable(vname);
rs2.add(new ProductionRule(v, sv.getTree()));
}
//System.err.println(" " + rs2);
rules.addAll(rs2);
}
}
}
Set finalStates = ((BottomUpTreeAutomaton)getSystem()).getFinalStates();
for (Iterator i = g.getRules().iterator(); i.hasNext(); ) {
for (Iterator j = finalStates.iterator(); j.hasNext(); ) {
IState finState = (IState) j.next();
IProductionRule rule = (IProductionRule) i.next();
IBinaryTreeVariable v = (IBinaryTreeVariable) rule.getLeft();
IBinaryTree bt = new BinaryTreeVariable(sv2name.get(finState, v));
IProductionRule r = new ProductionRule(v, bt);
rules.add(r);
}
}
ITreeGrammar result = new TreeGrammar((IBinaryTreeVariable)g.getStartSymbol(), rules);
//TreeGrammars.eliminateDanglingVariables(result, usedVars);
TreeGrammars.eliminateUselessRules(result);
return result;
}
}

View File

@ -0,0 +1,541 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
/**
* RTLComparator.java -- compare two tree grammars of binary trees.
*/
package com.ibm.wala.automaton.grammar.tree;
import java.util.*;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.*;
public class RTLComparator implements IRTLComparator {
static public boolean debug = false;
static private class Subtype {
// represent t1 <: t2
public Set left;
public Set right;
public Subtype(IBinaryTree t1, IBinaryTree t2){
Set l1 = new HashSet();
Set l2 = new HashSet();
l1.add(t1);
l2.add(t2);
this.left = l1;
this.right = l2;
}
public Subtype(IBinaryTree t1, Set t2){
Set l1 = new HashSet();
l1.add(t1);
this.left = l1;
this.right = t2;
}
public Subtype(Set t1, Set t2){
this.left = t1;
this.right = t2;
}
public String toString(){
return left + " <: " + right;
}
public int hashCode(){
return left.hashCode() + right.hashCode();
}
public boolean equals(Object obj){
if (this == obj) return true;
if (!getClass().equals(obj.getClass())) return false;
Subtype ty = (Subtype) obj;
if (left.equals(ty.left) && right.equals(ty.right)) {
return true;
}
else {
return false;
}
}
}
static private class Context {
final public ITreeGrammar left;
final public ITreeGrammar right;
final private Set set;
final private List stackTrace;
final private IMatchContext matchContext;
public Context(ITreeGrammar g1, ITreeGrammar g2){
this(g1, g2, new HashSet(), new ArrayList());
}
public Context(ITreeGrammar g1, ITreeGrammar g2, Set set, List stackTrace){
this.left = g1;
this.right = g2;
this.set = set;
this.stackTrace = stackTrace;
this.matchContext = new MatchContext();
}
public Set getLeftTrees(IBinaryTreeVariable v) {
return getLeftTrees(v, new HashSet());
}
public Set getLeftTrees(IBinaryTreeVariable v, Set history) {
if (history.contains(v)) {
return new HashSet();
}
history.add(v);
Set s = collectTrees(TreeGrammars.getRules(left, v));
Set ss = new HashSet();
for (Iterator i = s.iterator(); i.hasNext(); ) {
IBinaryTree t = (IBinaryTree) i.next();
if (t instanceof IBinaryTreeVariable) {
ss.addAll(getLeftTrees((IBinaryTreeVariable)t, history));
}
else {
ss.add(t);
}
}
return ss;
}
public Set getRightTrees(IBinaryTreeVariable v) {
return getRightTrees(v, new HashSet());
}
public Set getRightTrees(IBinaryTreeVariable v, Set history) {
if (history.contains(v)) {
return new HashSet();
}
history.add(v);
Set s = collectTrees(TreeGrammars.getRules(right, v));
Set ss = new HashSet();
for (Iterator i = s.iterator(); i.hasNext(); ) {
IBinaryTree t = (IBinaryTree) i.next();
if (t instanceof IBinaryTreeVariable) {
ss.addAll(getRightTrees((IBinaryTreeVariable)t, history));
}
else {
ss.add(t);
}
}
return ss;
}
public Set getLeftTrees(Set trees) {
return getLeftTrees(trees, new HashSet());
}
public Set getLeftTrees(Set trees, Set history) {
HashSet s = new HashSet();
for (Iterator i = trees.iterator(); i.hasNext(); ) {
IBinaryTree t = (IBinaryTree) i.next();
if (t instanceof IBinaryTreeVariable) {
s.addAll(getLeftTrees((IBinaryTreeVariable)t, history));
}
else {
s.add(t);
}
}
return s;
}
public Set getRightTrees(Set trees) {
return getRightTrees(trees, new HashSet());
}
public Set getRightTrees(Set trees, Set history) {
HashSet s = new HashSet();
for (Iterator i = trees.iterator(); i.hasNext(); ) {
IBinaryTree t = (IBinaryTree) i.next();
if (t instanceof IBinaryTreeVariable) {
s.addAll(getRightTrees((IBinaryTreeVariable)t, history));
}
else {
s.add(t);
}
}
return s;
}
private Set collectTrees(Set rules) {
HashSet s = new HashSet();
for (Iterator i = rules.iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
s.add(rule.getRight(0));
}
return s;
}
public IMatchContext getMatchContext() {
return matchContext;
}
public void add(Subtype ty){
set.add(ty);
}
public boolean contains(Subtype ty){
return set.contains(ty);
}
public Iterator iterator(){
return set.iterator();
}
public void addContext(Context ctx){
for( Iterator i = ctx.iterator(); i.hasNext(); ){
Subtype subtype = (Subtype) i.next();
add(subtype);
}
}
public void addTrace(Subtype subtype){
stackTrace.add(0, subtype);
}
public void popTrace(){
stackTrace.remove(0);
}
public Iterator stackTraceIterator(){
return stackTrace.iterator();
}
public String toString(){
return "#context:" + set.toString();
}
public Context dup(){
return new Context(left, right, new HashSet(set), new ArrayList(stackTrace));
}
}
public int compare(Object o1, Object o2) {
ITreeGrammar tg1 = (ITreeGrammar) o1;
ITreeGrammar tg2 = (ITreeGrammar) o2;
if (check(tg1, tg2)) {
if (check(tg2, tg1)) {
return 0;
}
else { // tg1 < tg2
return -1;
}
}
else {
if (check(tg2, tg1)) { // tg2 < tg1
return 1;
}
else {
return 0; // can't compare
}
}
}
public boolean contains(ITreeGrammar g1, ITreeGrammar g2) {
return check(g2, g1);
}
public boolean check(ITreeGrammar g1, ITreeGrammar g2) {
Context ctx = new Context(g1, g2);
return check(
(IBinaryTreeVariable) g1.getStartSymbol(),
(IBinaryTreeVariable) g2.getStartSymbol(),
ctx);
}
/**
* @param t1 types of tree
* @param t2 types of tree
* @return return the result of t1 <: t2
*/
private boolean check(IBinaryTree t1, IBinaryTree t2, Context ctx){
trace("check", t1, t2, ctx);
if( checkHyp(t1, t2, ctx) ){
return true;
}
if( checkAssum(t1, t2, ctx) ){
return true;
}
return false;
}
private boolean checkHyp(IBinaryTree t1, IBinaryTree t2, Context ctx){
trace("checkHyp", t1, t2, ctx);
Subtype subtype = new Subtype(t1, t2);
if( ctx.contains(subtype) ){
return true;
}
else{
return false;
}
}
private boolean checkAssum(IBinaryTree t1, IBinaryTree t2, Context ctx){
trace("checkAssum", t1, t2, ctx);
Subtype subtype = new Subtype(t1, t2);
Context ctx2 = ctx.dup();
ctx2.add(subtype);
if( check2(t1, t2, ctx2) ){
ctx.addContext(ctx2);
return true;
}
else{
return false;
}
}
private boolean check2(IBinaryTree t1, IBinaryTree t2, Context ctx){
trace("check2(IBinaryTree,IBinaryTree)", t1, t2, ctx);
Set l2 = new HashSet();
l2.add(t2);
return check2(t1, l2, ctx);
}
private boolean check2(Set t1, Set t2, Context ctx){
trace("check2(Set,Set)", t1, t2, ctx);
switch (t1.size()) {
case 0:
if( checkEmpty(t1, t2, ctx) ){
return true;
}
else{
return false;
}
case 1:
IBinaryTree u1 = pop(t1);
if( check2(u1, t2, ctx) ){
return true;
}
else{
return false;
}
default:
if( checkSplit(t1, t2, ctx) ){
return true;
}
else{
return false;
}
}
}
private boolean check2(IBinaryTree t1, Set t2, Context ctx){
trace("check2(IBinaryTree,Set)", t1, t2, ctx);
if( t1 instanceof IBinaryTreeVariable ){
Set l1 = ctx.getLeftTrees((IBinaryTreeVariable)t1);
if( check2(l1, t2, ctx) ){
return true;
}
else{
return false;
}
}
else {
if( t1 instanceof IParentBinaryTree ){
if( checkRec((IParentBinaryTree)t1, t2, ctx) ){
return true;
}
else{
return false;
}
}
else{
if( checkLeaf(t1, t2, ctx) ){
return true;
}
else{
return false;
}
}
}
}
private boolean checkEmpty(Set t1, Set t2, Context ctx){
trace("checkEmpty", t1, t2, ctx);
if( t1.isEmpty() ){
Subtype subtype = new Subtype(t1, t2);
ctx.add(subtype);
return true;
}
return false;
}
private boolean checkSplit(Set t1, Set t2, Context ctx){
trace("checkSplit", t1, t2, ctx);
Set tl1 = new HashSet(t1);
IBinaryTree hd1 = pop(tl1);
Context ctx2 = ctx.dup();
if( check2(hd1, t2, ctx2) ){
if( check2(tl1, t2, ctx2) ){
ctx.addContext(ctx2);
return true;
}
}
return false;
}
private boolean checkLeaf(IBinaryTree t1, Set t2, Context ctx){
trace("checkLeaf", t1, t2, ctx);
if( !(t1 instanceof IParentBinaryTree) ){
t2 = ctx.getRightTrees(t2);
trace("checkLeaf'", t1, t2, ctx);
for( Iterator i = t2.iterator(); i.hasNext(); ){
IBinaryTree s = (IBinaryTree) i.next();
if( !(s instanceof IParentBinaryTree) ){
Subtype subtype = new Subtype(t1, t2);
ctx.add(subtype);
return true;
}
}
}
return false;
}
private boolean checkRec(IParentBinaryTree t1, Set t2, Context ctx){
trace("checkRec", t1, t2, ctx);
ISymbol label1 = t1.getLabel();
IBinaryTree left1 = t1.getLeft();
IBinaryTree right1 = t1.getRight();
t2 = ctx.getRightTrees(t2);
trace("checkRec'", t1, t2, ctx);
Set l2 = new HashSet();
for( Iterator i = t2.iterator(); i.hasNext(); ){
IBinaryTree s = (IBinaryTree) i.next();
if( s instanceof IParentBinaryTree ){
ISymbol label2 = s.getLabel();
if( !label2.matches(label1, ctx.getMatchContext()) ){
continue;
}
}
else{
continue;
}
l2.add(s);
}
trace("checkRec''", t1, l2, ctx);
if( l2.isEmpty() ){
return false;
}
Set a = new HashSet();
Set b = new HashSet(l2);
Context ctx2 = ctx.dup();
while( true ){
if( !checkRec(left1, right1, a, b, ctx2) ){
return false;
}
if( b.isEmpty() ){
break;
}
IBinaryTree t = pop(b);
a.add(t);
}
ctx.addContext(ctx2);
return true;
}
private boolean checkRec(IBinaryTree left1, IBinaryTree right1, Set a, Set b, Context ctx){
trace("checkRec'''", left1, a, ctx);
trace("checkRec'''", right1, b, ctx);
Context ctx2 = ctx.dup();
for( Iterator i = a.iterator(); i.hasNext(); ){
IParentBinaryTree s = (IParentBinaryTree) i.next();
IBinaryTree left2 = s.getLeft();
IBinaryTree right2 = s.getRight();
if( check(left1, left2, ctx2) ){
ctx.addContext(ctx2);
return true;
}
}
for( Iterator i = b.iterator(); i.hasNext(); ){
IParentBinaryTree s = (IParentBinaryTree) i.next();
IBinaryTree left2 = s.getLeft();
IBinaryTree right2 = s.getRight();
if( check(right1, right2, ctx2) ){
ctx.addContext(ctx2);
return true;
}
}
return false;
}
private void trace(String msg, IBinaryTree t1, IBinaryTree t2, Context ctx){
Set l1 = new HashSet();
l1.add(t1);
Set l2 = new HashSet();
l2.add(t2);
trace(msg, l1, l2, ctx);
}
private void trace(String msg, IBinaryTree t1, Set t2, Context ctx){
Set l1 = new HashSet();
l1.add(t1);
trace(msg, l1, t2, ctx);
}
private void trace(String msg, Set t1, Set t2, Context ctx){
trace(msg + ": " + traceSymbolString(t1) + " <: " + traceSymbolString(t2));
trace(ctx.toString());
}
private void trace(String msg){
if (debug) {
System.err.println(msg);
}
}
private String traceSymbolString(Set l){
if( l.isEmpty() ){
return "{}";
}
else{
StringBuffer buff = new StringBuffer();
for (Iterator i = l.iterator(); i.hasNext(); ) {
ISymbol s = (ISymbol) i.next();
buff.append(s);
if (i.hasNext()) {
buff.append("|");
}
}
return buff.toString();
}
}
private IBinaryTree pop(Set trees) {
Iterator i = trees.iterator();
if (i.hasNext()) {
IBinaryTree t = (IBinaryTree) i.next();
i.remove();
return t;
}
else {
return null;
}
}
public boolean isEmpty(ITreeGrammar tg) {
ITreeGrammar emptyPattern = new TreeGrammar(
new BinaryTreeVariable("G"),
new IProductionRule[]{
new ProductionRule(new BinaryTreeVariable("G"), BinaryTree.LEAF),
});
return contains(emptyPattern, tg);
}
public static RTLComparator defaultComparator = new RTLComparator();
}

View File

@ -0,0 +1,77 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
import java.util.*;
import com.ibm.wala.automaton.*;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.*;
public class RTLTopDownTranslator extends RTLAbstractTranslator {
public RTLTopDownTranslator(TopDownTreeAutomaton automaton) {
super(automaton);
}
public ITreeGrammar translate(ITreeGrammar g) {
g = (ITreeGrammar) g.copy(SimpleGrammarCopier.defaultCopier);
TreeGrammars.normalize(g);
Set rules = new HashSet();
final StateVariable2Name sv2name = new StateVariable2Name(g);
for (Iterator i = getPrimitiveStates().iterator(); i.hasNext(); ) {
IState state = (IState) i.next();
for (Iterator j = g.getRules().iterator(); j.hasNext(); ) {
IProductionRule rule = (IProductionRule) j.next();
StateBinaryTree sv = new StateBinaryTree(state, (IBinaryTree) rule.getLeft());
String vname = sv2name.get(sv);
if (vname == null) throw(new AssertionError("should not be null."));
IBinaryTreeVariable v = new BinaryTreeVariable(vname);
StateBinaryTree bt = new StateBinaryTree(state, (IBinaryTree)rule.getRight(0));
Set rs = translate(v, bt, sv2name);
Set rs2 = new HashSet();
for (Iterator k = rs.iterator(); k.hasNext(); ){
final IProductionRule r = (IProductionRule) k.next();
IBinaryTree bt2 = (IBinaryTree) r.getRight(0);
bt2 = (IBinaryTree) bt2.copy(new DeepSymbolCopier(){
public ISymbol copy(ISymbol s) {
if (s instanceof StateBinaryTree) {
String vname = sv2name.get((StateBinaryTree)s);
return new BinaryTreeVariable(vname);
}
else {
return super.copy(s);
}
}
});
rs2.add(new ProductionRule(r.getLeft(), bt2));
}
rules.addAll(rs2);
}
}
IState initState = getSystem().getInitialState();
for (Iterator i = g.getRules().iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
IBinaryTreeVariable v = (IBinaryTreeVariable) rule.getLeft();
IBinaryTree bt = new BinaryTreeVariable(sv2name.get(initState, v));
IProductionRule r = new ProductionRule(v, bt);
rules.add(r);
}
ITreeGrammar result = new TreeGrammar((IBinaryTreeVariable)g.getStartSymbol(), rules);
//TreeGrammars.eliminateDanglingVariables(result, usedVars);
TreeGrammars.eliminateUselessRules(result);
return result;
}
}

View File

@ -0,0 +1,135 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
import java.util.*;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.*;
public class TreeGrammar extends SimpleGrammar implements ITreeGrammar {
public TreeGrammar(IBinaryTreeVariable startSymbol, IProductionRule rules[]) {
super(startSymbol, rules);
}
public TreeGrammar(IBinaryTreeVariable startSymbol, Set rules) {
super(startSymbol, rules);
}
public TreeGrammar(SimpleGrammar g) {
this((IBinaryTreeVariable)translateVariable(g.getStartSymbol()), collectRules(g.getRules()));
}
static public class VariableReplacer extends DeepSymbolCopier {
public ISymbol copy(ISymbol symbol) {
if ((symbol instanceof IVariable) && !(symbol instanceof IBinaryTreeVariable)) {
return new BinaryTreeVariable((IVariable)symbol);
}
else {
return super.copy(symbol);
}
}
}
static public VariableReplacer variableReplacer = new VariableReplacer();
static private ISymbol translateVariable(ISymbol s) {
if (s instanceof IBinaryTree) {
return s;
}
else {
return s.copy(variableReplacer);
}
}
static private Set collectRules(Set rules) {
final Set rtgRules = new HashSet();
final Set cfgRules = new HashSet();
for (Iterator i = rules.iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
if (rule.getRight().size() == 1) {
if (rule.getRight(0) instanceof IBinaryTree) {
if (rule.getLeft() instanceof IBinaryTreeVariable) {
rtgRules.add(rule);
}
else {
IProductionRule r = new ProductionRule((IVariable)translateVariable(rule.getLeft()), rule.getRight());
rtgRules.add(r);
}
}
else if (rule.getRight(0) instanceof IVariable) {
IVariable v = (IVariable)rule.getRight(0);
IProductionRule r = new ProductionRule((IVariable)translateVariable(rule.getLeft()), new BinaryTreeVariable(v));
rtgRules.add(r);
}
else if (rule.getRight(0) instanceof IValueSymbol) {
cfgRules.add(rule);
}
else if (rule.getRight(0) instanceof Symbol){
cfgRules.add(rule);
}
else {
throw(new RuntimeException("unsupported symbol: " + rule.getRight(0)));
/*
ISymbol s = rule.getRight(0).copy(new DeepSymbolCopier(){
public ISymbol copy(ISymbol s) {
if (s instanceof IVariable) {
return translateVariable((IVariable)s);
}
else {
return super.copy(s);
}
}
});
IProductionRule r = new ProductionRule((IVariable)translateVariable(rule.getLeft()), s);
rtgRules.add(r);
*/
}
}
else {
cfgRules.add(rule);
}
}
for (Iterator i = cfgRules.iterator(); i.hasNext(); ) {
IProductionRule r = (IProductionRule) i.next();
IContextFreeGrammar cfg = new ContextFreeGrammar(r.getLeft(), rules);
Grammars.eliminateUselessRules(cfg);
//Grammars.eliminateDanglingVariables(cfg);
IProductionRule t = new ProductionRule((IVariable)translateVariable(r.getLeft()), new BinaryTree(new CFGSymbol(cfg)));
rtgRules.add(t);
}
return rtgRules;
}
public SimpleGrammar toSimple() {
SimpleGrammar g = super.toSimple();
final Set newRules = new HashSet();
g.traverseRules(new IRuleVisitor(){
public void onVisit(IProductionRule rule) {
if (rule.getLeft() instanceof IBinaryTreeVariable) {
IBinaryTreeVariable btv = (IBinaryTreeVariable) rule.getLeft();
newRules.add(new ProductionRule(btv, btv.getLabel()));
newRules.add(new ProductionRule((IVariable)btv.getLabel(), rule.getRight()));
}
else {
newRules.add(rule);
}
}
});
IVariable startVar = g.getStartSymbol();
if (startVar instanceof IBinaryTreeVariable) {
startVar = (IVariable) ((IBinaryTreeVariable)startVar).getLabel();
}
g = new SimpleGrammar(startVar, newRules);
return g;
}
}

View File

@ -0,0 +1,240 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.grammar.tree;
import java.util.*;
import com.ibm.wala.automaton.AUtil;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.*;
public class TreeGrammars extends Grammars {
/**
* normalize a regular tree grammar.
* @param g regular tree grammar (ITreeGrammar object)
*/
static public void normalize(ITreeGrammar g, IVariableFactory<IBinaryTreeVariable> varFactory) {
refreshProductionRules(g, new DeepRuleCopier(DeepSymbolCopier.defaultCopier));
eliminateUnitRules(g);
if (varFactory == null) {
varFactory =
new BinaryTreeVariableFactory(
new FreshVariableFactory(
SimpleVariableFactory.defaultFactory, g));
}
IBinaryTreeVariable leafVar = null;
Set newRules = new HashSet();
// obtain/create a variable for the leaf.
/*
for (Iterator i = g.getRules().iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
IBinaryTree bt = (IBinaryTree) rule.getRight(0);
if (bt.equals(BinaryTree.LEAF)) {
if (g.getRules(rule.getLeft()).size()==1) {
leafVar = (IBinaryTreeVariable) rule.getLeft();
}
}
}
*/
if (leafVar == null) {
leafVar = varFactory.createVariable("N");
IProductionRule r = new ProductionRule(leafVar, BinaryTree.LEAF);
g.getRules().add(r);
}
do {
newRules.clear();
for (Iterator i = g.getRules().iterator(); i.hasNext(); ) {
IProductionRule rule = (IProductionRule) i.next();
IBinaryTree bt = (IBinaryTree) rule.getRight(0);
if (bt.equals(BinaryTree.LEAF)){
// do nothing
}
else if (bt instanceof IParentBinaryTree) {
IParentBinaryTree pbt = (IParentBinaryTree) bt;
if (!(pbt.getLeft() instanceof IBinaryTreeVariable)) {
if (pbt.getLeft().equals(BinaryTree.LEAF)) {
pbt.setLeft(leafVar);
}
else {
IBinaryTreeVariable v = varFactory.createVariable("N");
IProductionRule r = new ProductionRule(v, pbt.getLeft());
pbt.setLeft(v);
newRules.add(r);
}
}
if (!(pbt.getRight() instanceof IBinaryTreeVariable)) {
if (pbt.getRight().equals(BinaryTree.LEAF)) {
pbt.setRight(leafVar);
}
else {
IBinaryTreeVariable v = varFactory.createVariable("N");
IProductionRule r = new ProductionRule(v, pbt.getRight());
pbt.setRight(v);
newRules.add(r);
}
}
}
else {
// TODO:
throw(new RuntimeException("unimplemented yet."));
}
}
g.getRules().addAll(newRules);
} while(!newRules.isEmpty());
}
static public void normalize(ITreeGrammar g) {
normalize(g, null);
}
static public void reduce(final ITreeGrammar g) {
refreshProductionRules(g);
for (Iterator i = g.getRules().iterator(); i.hasNext(); ) {
final IProductionRule rule = (IProductionRule) i.next();
IBinaryTree bt = (IBinaryTree) rule.getRight(0);
bt = (IBinaryTree) bt.copy(new DeepSymbolCopier(){
private Set history = new HashSet();
{
history.add(rule.getLeft());
}
public ISymbol copy(ISymbol s) {
if (s instanceof IBinaryTreeVariable) {
Set drules = g.getRules((IBinaryTreeVariable)s);
if (drules.size()==1) {
IProductionRule drule = (IProductionRule) drules.iterator().next();
if (!history.contains(drule.getLeft())) {
return drule.getRight(0).copy(this);
}
}
}
return super.copy(s);
}
});
rule.getRight().clear();
rule.getRight().add(bt);
}
eliminateUselessRules(g);
}
public static void append(ITreeGrammar g, IBinaryTree s) {
append(g, s, new BinaryTreeVariableFactory(new FreshVariableFactory(SimpleVariableFactory.defaultFactory, g)));
}
public static void append(ITreeGrammar g, final IBinaryTree s, final IVariableFactory<IBinaryTreeVariable> varFactory) {
normalize(g, varFactory);
appendInternal(g, s, varFactory);
eliminateUselessRules(g);
}
protected static void appendInternal(ITreeGrammar g, final IBinaryTree s, IVariableFactory<IBinaryTreeVariable> varFactory) {
final Set<IProductionRule> newRules = new HashSet<IProductionRule>();
final Map<IBinaryTreeVariable, IBinaryTreeVariable> varMap = new HashMap<IBinaryTreeVariable, IBinaryTreeVariable>();
for (Iterator<IProductionRule> i = g.getRules().iterator(); i.hasNext(); ) {
IProductionRule r = i.next();
IBinaryTreeVariable v = (IBinaryTreeVariable) r.getLeft();
IBinaryTreeVariable newVar = null;
if (varMap.containsKey(v)) {
newVar = varMap.get(v);
}
else {
newVar = varFactory.createVariable(variablePrefix);
varMap.put(v, newVar);
}
IProductionRule newRule = r.copy(new DeepRuleCopier(DeepSymbolCopier.defaultCopier));
newRule.setLeft(newVar);
newRules.add(newRule);
}
final Set<IProductionRule> rules = new HashSet<IProductionRule>();
for (Iterator<IProductionRule> i = newRules.iterator(); i.hasNext(); ) {
IProductionRule r = i.next();
r = (IProductionRule) r.copy(SimpleRuleCopier.defaultCopier);
if (r.getRight(0) instanceof IParentBinaryTree) {
IParentBinaryTree pbt = (IParentBinaryTree) r.getRight(0);
IBinaryTreeVariable v = (IBinaryTreeVariable) pbt.getRight();
if (varMap.containsKey(v)) {
pbt.setRight(varMap.get(v));
}
rules.add(r);
}
else if (r.getRight(0).equals(BinaryTree.LEAF)) {
r.getRight().clear();
r.getRight().add(s);
rules.add(r);
}
else if (r.getRight(0) instanceof IBinaryTreeVariable) {
// do nothing
}
else {
throw(new RuntimeException("unexpected symbol: " + r.getRight(0)));
}
}
g.getRules().addAll(rules);
g.setStartSymbol(varMap.get(g.getStartSymbol()));
}
public static void append(IBinaryTree bt, IBinaryTree s) {
if (bt instanceof IParentBinaryTree) {
IParentBinaryTree pbt = (IParentBinaryTree) bt;
if (pbt.getRight().equals(BinaryTree.LEAF)) {
pbt.setRight(s);
}
else {
append(pbt.getRight(), s);
}
}
else {
throw(new RuntimeException("should not append the tree to the leaf"));
}
}
public static void appendChild(ITreeGrammar g, IBinaryTree s) {
appendChild(g, s, new BinaryTreeVariableFactory(new FreshVariableFactory(SimpleVariableFactory.defaultFactory, g)));
}
public static void appendChild(ITreeGrammar g, IBinaryTree s, IVariableFactory<IBinaryTreeVariable> varFactory) {
normalize(g, varFactory);
appendChildInternal(g, s, varFactory);
eliminateUselessRules(g);
}
protected static void appendChildInternal(ITreeGrammar g, IBinaryTree s, IVariableFactory<IBinaryTreeVariable> varFactory) {
Map<IBinaryTreeVariable, IBinaryTreeVariable> varMap = new HashMap<IBinaryTreeVariable, IBinaryTreeVariable>();
Set<IProductionRule> rules = new HashSet<IProductionRule>();
IBinaryTreeVariable origStart = (IBinaryTreeVariable) g.getStartSymbol();
IBinaryTreeVariable newStart = varFactory.createVariable(variablePrefix);
for (Iterator<IProductionRule> i = g.getRules(origStart).iterator(); i.hasNext(); ) {
IProductionRule r = i.next();
IBinaryTreeVariable v = (IBinaryTreeVariable) r.getLeft();
IProductionRule newRule = r.copy(new DeepRuleCopier(DeepSymbolCopier.defaultCopier));
newRule.setLeft(newStart);
rules.add(newRule);
}
for (Iterator<IProductionRule> i = rules.iterator(); i.hasNext(); ) {
IProductionRule r = i.next();
if (r.getRight(0) instanceof IParentBinaryTree) {
IParentBinaryTree pbt = (IParentBinaryTree) r.getRight(0);
IBinaryTreeVariable v = (IBinaryTreeVariable) pbt.getLeft();
g.setStartSymbol(v);
appendInternal(g, s, varFactory);
pbt.setLeft((IBinaryTreeVariable)g.getStartSymbol());
g.setStartSymbol(origStart);
}
}
g.getRules().addAll(rules);
g.setStartSymbol(newStart);
}
}

View File

@ -0,0 +1 @@
y.output

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,908 @@
/*
* Automaton/Grammar/Pattern Parser
*
* AmtParser.java is generated from this file by kmyacc
* that is available at http://www005.upp.so-net.ne.jp/kmori/kmyacc/.
*
* See also doc/parser-guide.txt more in detials.
*/
%{
package com.ibm.capa.util.automaton.parser;
import java.io.*;
import java.nio.*;
import sun.io.*;
import java.util.*;
import java.lang.reflect.*;
import com.ibm.wala.automaton.*;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.grammar.tree.*;
import com.ibm.wala.automaton.regex.string.*;
import com.ibm.wala.automaton.regex.tree.*;
import com.ibm.wala.automaton.string.*;
import com.ibm.wala.automaton.tree.*;
%}
%token SYMBOL STRING VARIABLE DVARIABLE
%token AND OR EQ
%token INTEGER DOUBLE
%token STATE
%token ARROW
%token NEW
%token NULL
%token AS REF
/* 2006 10 16, tabee@jp.ibm.com */
%token CHARRANGE CHAR CHARSETEND
%token SEARCH ALIAS DELETE
%token TREEGRAMMAR
%type <String> SYMBOL STRING VARIABLE DVARIABLE
%type <Long> INTEGER
%type <Double> DOUBLE
%type <String> STATE
/* 2006 10 16, tabee@jp.ibm.com */
%type <Character[]> CHARRANGE
%type <Character> CHAR
%type <ITreeGrammar> TREEGRAMMAR
%type <Object> expression instantiation parameter
%type <IVariable> variable dvariable
%type <IBinaryTreeVariable> btvariable
%type <ISymbol> symbol basicSymbol
%type <IState> state
%type <List> expressions parameters symbols
%type <Map> propertyDefinition propertyDefinitions
%type <String> propertyName className classPath
%type <ITree> tree treeChild
%type <ITreeGrammar> treeGrammar
%type <Set> treeProductionRules
%type <IProductionRule> treeProductionRule
%type <List> treeChildren
%type <IBinaryTree> btree btreeChild
%type <IPattern> stringPattern stringPatternOrEmpty treePattern
%type <IPattern> charSet charSetOrComplementCharSet
%type <IPattern> stringPatternExpr
%left '='
%left EQ
%left OR AND
%left '+' '-'
%left '*' '/'
%left AS
%left '|', '&'
%right ','
%nonassoc '~', '*', '+', '?'
%%
start
: definitions
| expression { result.put(lastVariable, $1); }
;
definitions
: definition definitions
| /* empty */
;
definition
: variable '=' expression enddef { result.put($1, $3); }
| DELETE variable { result.remove($2); }
| SEARCH classPath enddef { searchPath.add($2); }
| DELETE SEARCH classPath enddef { searchPath.remove($3); }
| ALIAS basicSymbol '=' symbol enddef { alias.put($2,$4); }
| DELETE ALIAS basicSymbol enddef { alias.remove($3); }
;
expression
: instantiation { $$ = $1; }
| instantiation '{' propertyDefinitions '}' {
Object instance = $1;
Map propDefs = $3;
for (Iterator i = propDefs.keySet().iterator(); i.hasNext(); ) {
String propName = (String) i.next();
Object propValue = propDefs.get(propName);
try {
String setterName = "set" + Character.toUpperCase(propName.charAt(0)) + propName.substring(1);
instance.getClass().getMethod(setterName, new Class[]{propValue.getClass()}).invoke(instance, new Object[]{propValue});
} catch (NoSuchMethodException e) {
try {
instance.getClass().getField(propName).set(instance, propValue);
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (NoSuchFieldException e1) {
e1.printStackTrace();
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
$$ = instance;
}
| '{' expressions '}' { $$ = new HashSet($2); }
| '[' expressions ']' { $$ = new ArrayList($2); }
| STRING { $$ = $1; }
| INTEGER { $$ = $1; }
| DOUBLE { $$ = $1; }
| symbol { $$ = $1; }
| state { $$ = $1; }
| variable { $$ = result.get($1); }
| dvariable { $$ = $1; }
| tree { $$ = $1; }
| btree { $$ = $1; }
| stringPatternExpr { $$ = $1; }
| '%' '{' treePattern '}' { $$ = $3; }
| '(' expression ')' { $$ = $2; }
| treeGrammar { $$ = $1; }
;
stringPatternExpr
: '/' { inStringPattern = 0; } stringPatternOrEmpty { inStringPattern = -1; } '/' { $$ = $3; }
;
instantiation
: className '(' parameters ')' {
String cname = $1;
List params = $3;
Class klasses[] = new Class[params.size()];
Object objs[] = new Object[params.size()];
for (ListIterator i = params.listIterator(); i.hasNext(); ) {
int index = i.nextIndex();
Object val = i.next();
klasses[index] = val.getClass();
objs[index] = val;
}
Object instance = null;
for (Iterator i = searchPath.iterator(); i.hasNext(); ) {
String path = (String) i.next();
try {
String fullcname = null;
if (path == null || path.length() == 0) {
fullcname = cname;
}
else if (path.charAt(path.length()-1) == '.') {
fullcname = path + cname;
}
else {
fullcname = path + "." + cname;
}
Class klass = CLASSLOADER.loadClass(fullcname);
Constructor constructors[] = klass.getConstructors();
for (int j = 0; j < constructors.length; j++) {
try {
instance = constructors[j].newInstance(objs);
break;
}
catch(Exception e) {
if (j == constructors.length-1) {
throw(new RuntimeException(e));
}
}
}
break;
} catch (Exception e) {
if(!i.hasNext()) {
throw(new RuntimeException(e));
}
}
}
$$ = instance;
}
;
expressions
: expression ',' expressions { List l = $3; l.add(0, $1); $$ = l; }
| expression { List l = new ArrayList(); l.add(0, $1); $$ = l; }
| /* empty */ { $$ = new ArrayList(); }
;
tree
: symbol '[' treeChildren ']' { Tree t = new Tree($1, $3); $$ = t; }
;
treeChild
: tree { $$ = $1; }
| symbol { Tree t = new Tree($1); $$ = t; }
| variable { $$ = result.get($1); }
| dvariable { $$ = new TreeVariable($1); }
;
treeChildren
: treeChild ',' treeChildren { List l = $3; l.add(0, $1); $$ = l; }
| treeChild { List l = new ArrayList(); l.add($1); $$ = l; }
| /* empty */ { List l = new ArrayList(); $$ = l; }
;
btree
: symbol '[' btreeChild ';' btreeChild ']' { BinaryTree t = new BinaryTree($1, $3, $5); $$ = t; }
| stringPatternExpr '[' btreeChild ';' btreeChild ']' { BinaryTree t = new BinaryTree(new StringPatternSymbol($1), $3, $5); $$ = t; }
;
btreeChild
: btree { $$ = $1; }
| symbol { BinaryTree t = new BinaryTree($1); $$ = t; }
| variable { $$ = result.get($1); }
| dvariable { $$ = new BinaryTreeVariable($1); }
| NULL { $$ = null; }
| stringPatternExpr { BinaryTree t = new BinaryTree(new StringPatternSymbol($1)); $$ = t; }
| /* empty */ { $$ = null; }
;
stringPattern
: symbol { $$ = new SymbolPattern($1); }
| stringPattern ',' stringPattern { $$ = new ConcatenationPattern($1, $3); }
| stringPattern ',' { $$ = $1; }
| stringPattern '*' { $$ = new IterationPattern($1, true); }
| stringPattern '+' { $$ = new IterationPattern($1, false); }
| stringPattern '?' { $$ = new UnionPattern($1, new EmptyPattern()); }
| stringPattern '|' stringPattern { $$ = new UnionPattern($1,$3); }
| stringPattern '&' stringPattern { $$ = new IntersectionPattern($1,$3); }
| stringPattern '-' stringPattern { $$ = new IntersectionPattern($1, new ComplementPattern($3)); }
| '~' stringPattern { $$ = new ComplementPattern($2); }
| '(' { inStringPattern++; varStack.push(new Variable(Integer.toString(inStringPattern))); } stringPatternOrEmpty ')' { $$ = new VariableBindingPattern($3, (IVariable)varStack.pop()); }
/* 2006 10 16, tabee@jp.ibm.com Begin */
| '[' { inCharSetPattern++; charSetBegin = true; isComplementCharSet = false; } charSetOrComplementCharSet {
inCharSetPattern--;
$$ = $3;
}
;
charSetOrComplementCharSet
: '^' charSet { $$ = new IntersectionPattern(new SymbolPattern(new CharPatternSymbol("\\.")), new ComplementPattern($2)); }
| charSet { $$ = $1; }
charSet
:
| CHARRANGE CHARSETEND {
$$ = charRange((Character[])$1);
}
| CHARRANGE charSet {
IPattern p1 = charRange((Character[])$1);
$$ = new UnionPattern(p1, $2);
}
| CHAR CHARSETEND { Character c = (Character)$1; $$ = new SymbolPattern(new CharSymbol(c.charValue())); }
| CHAR charSet {
Character c = (Character)$1;
IPattern p1 = new SymbolPattern(new CharSymbol(c.charValue()));
$$= new UnionPattern(p1, $2);
}
/* 2006 10 16, tabee@jp.ibm.com End */
stringPatternOrEmpty
: stringPattern { $$ = $1; }
| /* empty */ { $$ = new EmptyPattern(); }
;
treePattern
: symbol { $$ = new SymbolPattern($1); }
| '(' ')' { $$ = new EmptyPattern(); }
| treePattern '*' { $$ = new IterationPattern($1, true); }
| treePattern '+' { $$ = new IterationPattern($1, false); }
| treePattern ',' treePattern { $$ = new ConcatenationPattern($1, $3); }
| treePattern '|' treePattern { $$ = new UnionPattern($1,$3); }
| treePattern AS variable { $$ = new VariableBindingPattern($1,$3); }
| REF variable { $$ = new VariableReferencePattern($2); }
| REF '(' variable ')' { $$ = new VariableReferencePattern($3); }
| '~' treePattern { $$ = new ComplementPattern($2); }
| '(' treePattern ')' { $$ = $2; }
;
treeGrammar
: TREEGRAMMAR btvariable '{' treeProductionRules '}' { $$ = new TreeGrammar($2, $4); }
;
btvariable
: dvariable { $$ = new BinaryTreeVariable($1); }
;
treeProductionRules
: treeProductionRule treeProductionRules { Set rules = $2; rules.add($1); $$ = rules; }
| /* empty */ { $$ = new HashSet(); }
;
treeProductionRule
: btvariable ARROW btree enddef { $$ = new ProductionRule($1, $3); }
| btvariable ARROW variable enddef { $$ = new ProductionRule($1, (IBinaryTree)result.get($3)); }
| btvariable ARROW NULL enddef { $$ = new ProductionRule($1, BinaryTree.LEAF); }
| btvariable ARROW enddef { $$ = new ProductionRule($1, BinaryTree.LEAF); }
;
propertyDefinitions
: propertyDefinition propertyDefinitions {
Map m1 = $1;
Map m2 = $2;
for (Iterator i = m1.keySet().iterator(); i.hasNext(); ) {
Object key = i.next();
Object val = m1.get(key);
m2.put(key, val);
}
$$ = m2;
}
| /* empty */ { $$ = new HashMap(); }
;
propertyDefinition
: propertyName '=' expression {
Map m = new HashMap();
m.put($1, $3);
$$ = m;
}
;
propertyName
: SYMBOL { $$ = $1; }
;
className
: classPath { $$ = $1; }
;
classPath
: symbol { $$ = $1.getName(); }
| symbol '.' classPath { $$ = $1.getName() + "." + $3; }
| STRING { $$ = $1; }
;
parameters
: parameter ',' parameters { List l = $3; l.add(0, $1); $$ = l; }
| parameter { List l = new ArrayList(); l.add(0, $1); $$ = l; }
| /* empty */ { $$ = new ArrayList(); }
;
parameter
: expression { $$ = $1; }
;
variable
: VARIABLE { $$ = new Variable($1); }
;
dvariable
: DVARIABLE { $$ = new Variable($1); }
;
symbols
: symbol ',' symbols { $3.add(0, $1); $$ = $3; }
| symbol { List l = new LinkedList(); l.add($1); $$ = l; }
;
symbol
: basicSymbol {
ISymbol s = $1;
if (alias.containsKey(s)) {
s = (ISymbol) alias.get(s);
}
$$ = s;
}
;
basicSymbol
: SYMBOL {
String s = $1;
if (inStringPattern >= 0) {
if (s.charAt(0) == '\\' && s.length() > 1) {
$$ = new CharPatternSymbol(s);
}
else {
$$ = new CharSymbol(s);
}
}
else {
$$ = new StringSymbol(s);
}
}
| SYMBOL ':' symbol { $$ = new PrefixedSymbol(new StringSymbol($1), $3); }
;
state
: STATE { $$ = new State($1); }
;
enddef
: ';'
| /* empty */
;
enddef1
: ';'
;
%%
/* Lexical analyzer */
static private ClassLoader CLASSLOADER = AmtParser.class.getClassLoader();
static private int BUFF_SIZE = 256;
private Stack ch = new Stack();
private InputStream inputStream = System.in;
private Map result = new HashMap();
private Map alias = new HashMap();
private List searchPath = new ArrayList(); { searchPath.add(""); };
private int lineno = 1;
private CharToByteConverter c2b = CharToByteConverter.getDefault();
private int inStringPattern = -1;
private Stack varStack = new Stack();
private int nextChar = -1;
private IVariable lastVariable = new Variable("_");
/* 2006 10 16, tabee@jp.ibm.com */
// They are initialized each time parsing a character-set expression
private int inCharSetPattern = -1;
private boolean charSetBegin = true;
private boolean isComplementCharSet = false;
public AmtParser() {
}
public AmtParser(String conv) {
try {
c2b = CharToByteConverter.getConverter(conv);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
c2b = CharToByteConverter.getDefault();
}
}
public List getSearchPath() {
return searchPath;
}
public void setAlias(ISymbol s1, ISymbol s2) {
alias.put(s1, s2);
}
public void setAlias(String s1, String s2) {
setAlias(new StringSymbol(s1), new StringSymbol(s2));
}
public void unsetAlias(ISymbol s1) {
alias.remove(s1);
}
public void unsetAlias(String s1) {
unsetAlias(new StringSymbol(s1));
}
public Map getResult(){
return result;
}
public void setInputStream(InputStream istream){
inputStream = istream;
}
public Map parse(InputStream istream){
setInputStream(istream);
yyparse();
return getResult();
}
public Map parse(String str) {
char cs[] = str.toCharArray();
byte bs[];
try {
bs = c2b.convertAll(cs);
} catch (MalformedInputException e) {
bs = new byte[0];
}
ByteArrayInputStream bstream = new ByteArrayInputStream(bs);
return parse(bstream);
}
public Object getParsedResult(String str) {
return parse(str).get(lastVariable);
}
private int getch() {
int c = 0;
if (ch.isEmpty()) {
try {
c = inputStream.read();
} catch (java.io.IOException e) {
throw new Error(e.getMessage());
}
}
else{
c = ((Integer)ch.pop()).intValue();
}
if( c == '\n' ){
lineno = lineno + 1;
}
return c;
}
private void ungetch(int c) {
if( c == '\n' ) {
lineno = lineno - 1;
}
ch.push(new Integer(c));
}
static private boolean isVariableChar(char c){
return Character.isJavaIdentifierPart((char)c)
|| (c == '\'') || (c == '~') || (c == '^');
}
static private boolean isSymbolChar(char c){
return Character.isJavaIdentifierPart((char)c)
|| (c == '\'') || (c == '~') || (c == '^');
}
static private boolean isSymbolFirstChar(char c){
return Character.isJavaIdentifierStart((char)c)
|| (c == '@');
}
static final char specials[] = new char[]{
'(', ')', '[', ']', '|', '&', '*', '+', '-', '/', '~', '^', '!', '?',
};
static final char concatChars[] = new char[]{
')', ']', '*', '+', '?',
};
static final Map charMap = new HashMap();
static {
charMap.put("\\n", "\n");
charMap.put("\\r", "\r");
charMap.put("\\t", "\t");
charMap.put("\\\\", "\\");
charMap.put("\\.", ".");
charMap.put(".", "\\.");
}
static private boolean isPatternSpecialChar(char c) {
for (int i = 0; i < specials.length; i++) {
if (c == specials[i]) return true;
}
return false;
}
static private boolean isPatternConcatChar(char c) {
for (int i = 0; i < concatChars.length; i++) {
if (c == concatChars[i]) return true;
}
return false;
}
static private boolean isPatternSymbol(char c) {
return !isPatternSpecialChar(c);
}
/* 2006 10 16, tabee@jp.ibm.com */
private IPattern charRange(Character[] cs) {
IPattern pat = null;
char c1 = cs[0].charValue();
char c2 = cs[1].charValue();
for (char c = c1; c <= c2; c++) {
if (pat == null) {
pat = new SymbolPattern(new CharSymbol(c));
} else {
IPattern p2 = new SymbolPattern(new CharSymbol(c));
pat = new UnionPattern(pat, p2);
}
}
if (pat == null) pat = new EmptyPattern();
return pat;
}
int yylexForCharSetPattern() {
yylval = null;
for (;;) {
int c = getch();
if (c < 0){
return 0;
}
if ((char)c == '^') {
if (charSetBegin && !isComplementCharSet) {
isComplementCharSet = true;
yylval = Character.toString((char)c);
return c;
}
}
if ((char)c == ']') {
if (charSetBegin) {
yylval = new Character(']');
} else {
yylval = Character.toString((char)c);
return CHARSETEND;
}
} else if ((char)c == '-') {
if (charSetBegin) {
yylval = new Character('-');
} else {
int lookahead = getch();
if ((char)lookahead == ']') {
ungetch(']');
yylval = new Character('-');
return CHAR;
}
yyerror("Unreachable code.");
}
} else {
yylval = new Character((char)c);
}
if (charSetBegin) {
charSetBegin = false;
}
/*
If the next character is '-', it is a character-range expression
unless it's not the last character inside '[...]'
*/
int lookahead = getch();
if ((char)lookahead == '-') {
lookahead = getch();
if ((char)lookahead == ']') {
ungetch(']');
ungetch('-');
return CHAR;
}
yylval = new Character[] { (Character)yylval, new Character((char)lookahead) };
return CHARRANGE;
} else {
ungetch(lookahead);
return CHAR;
}
}
}
int yylexForStringPattern() {
yylval = null;
for (;;) {
if (nextChar > 0) {
int c = nextChar;
nextChar = -1;
return c;
}
int c = getch();
if (c < 0){
return 0;
}
else if (isPatternSymbol((char)c)) {
yylval = Character.toString((char)c);
if (c == '\\') {
c = getch();
if (c > 0) {
yylval = yylval + Character.toString((char)c);
}
if (charMap.containsKey((String)yylval)) {
yylval = charMap.get((String)yylval);
}
else if (isPatternSpecialChar((char)c)) {
yylval = Character.toString((char)c);
}
}
else {
if (charMap.containsKey((String)yylval)) {
yylval = charMap.get((String)yylval);
}
}
nextChar = ',';
return SYMBOL;
}
else {
yylval = Character.toString((char)c);
if (isPatternConcatChar((char)c)) {
nextChar = ',';
}
if (charMap.containsKey((String)yylval)) {
yylval = charMap.get((String)yylval);
return SYMBOL;
}
else {
return c;
}
}
}
}
int yylex() {
if (inCharSetPattern >= 0) {
return yylexForCharSetPattern();
}
if (inStringPattern >= 0) {
return yylexForStringPattern();
}
yylval = null;
for (;;) {
int c = getch();
if (c < 0){
return 0;
}
else if (c == '#') {
while (c != 0) {
if( c == '\n' ) break;
c = getch();
}
}
else if (c == ' ' || c == '\t' || c == '\r' || c == '\n' ){
}
else{
if (c == '$') {
int n = 0;
boolean dvar = false;
char[] buf = new char[BUFF_SIZE];
buf[n++] = (char)c;
c = getch();
if (c == '$') {
dvar = true;
c = getch();
}
while (isVariableChar((char)c)) {
buf[n++] = (char)c;
c = getch();
}
ungetch(c);
yylval = new String(buf, 1, n-1);
return (dvar ? DVARIABLE : VARIABLE);
}
if (c == '<') {
int n = 0;
char[] buf = new char[BUFF_SIZE];
buf[n++] = (char)c;
c = getch();
while (c != '>') {
buf[n++] = (char)c;
c = getch();
}
buf[n++] = (char)c;
yylval = new String(buf, 1, n-2);
return STATE;
}
if (c == '"' || c == '\'') {
int n = 0;
char[] buf = new char[BUFF_SIZE];
buf[n++] = (char)c;
int c2 = getch();
while (c2 != c) {
buf[n++] = (char)c2;
c2 = getch();
if( c2 == '\\' ){
c2 = getch();
continue;
}
}
buf[n++] = (char)c2;
yylval = new String(buf, 1, n-2);
if (c == '"') {
return STRING;
}
else{
return SYMBOL;
}
}
if (c == '-') {
int c2 = getch();
if (c2 == '>') {
yylval = "->";
return ARROW;
}
else{
ungetch(c2);
}
}
if (Character.isDigit((char)c) || c == '-') {
int n = 0;
char[] buf = new char[BUFF_SIZE];
buf[n++] = (char)c;
c = getch();
while (Character.isDigit((char)c) || c == '.') {
buf[n++] = (char)c;
c = getch();
}
ungetch(c);
String numStr = new String(buf, 0, n);
if( numStr.indexOf(".") >= 0 ){
yylval = new Double(numStr);
return DOUBLE;
}
else{
yylval = new Long(numStr);
return INTEGER;
}
}
if (c == '&'){
c = getch();
if (c == '&') {
return AND;
}
else{
ungetch(c);
yylval = Character.toString('&');
return '&';
}
}
if (c == '|'){
c = getch();
if (c == '|') {
return OR;
}
else{
ungetch(c);
yylval = Character.toString('|');
return '|';
}
}
if (c == '='){
c = getch();
if (c == '=') {
return EQ;
}
else{
ungetch(c);
yylval = Character.toString('=');
return '=';
}
}
if (isSymbolFirstChar((char)c)) {
int n = 0;
char[] buf = new char[BUFF_SIZE];
buf[n++] = (char)c;
c = getch();
while (isSymbolChar((char)c)) {
buf[n++] = (char)c;
c = getch();
}
ungetch(c);
yylval = new String(buf, 0, n);
if (yylval.equals("new")) {
return NEW;
}
else if (yylval.equals("null")) {
return NULL;
}
else if (yylval.equals("as")) {
return AS;
}
else if (yylval.equals("ref")) {
return REF;
}
else if (yylval.equals("search")) {
return SEARCH;
}
else if (yylval.equals("alias")) {
return ALIAS;
}
else if (yylval.equals("delete")) {
return DELETE;
}
else if (yylval.equals("TreeGrammar")) {
return TREEGRAMMAR;
}
else {
return SYMBOL;
}
}
else{
yylval = Character.toString((char)c);
return c;
}
}
}
}
void yyerror(String msg) {
Object t = (yylval == null) ? "" : yylval;
System.err.println("line " + lineno + "(before '" + t + "'): " + msg);
}

View File

@ -0,0 +1,46 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.List;
import com.ibm.wala.automaton.AUtil;
import com.ibm.wala.automaton.string.IAutomaton;
import com.ibm.wala.automaton.string.ISymbol;
public abstract class AbstractPattern implements IPattern {
private IAutomaton compiledPattern = null;
public IAutomaton compile(IPatternCompiler compiler) {
if (compiledPattern == null) {
compiledPattern = compiler.compile(this);
}
return compiledPattern;
}
public boolean matches(List sequence) {
return compiledPattern.accept(sequence);
}
public boolean matches(ISymbol symbol) {
return matches(AUtil.list(new ISymbol[]{symbol}));
}
abstract public void traverse(IPatternVisitor visitor);
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw(new RuntimeException(e));
}
}
}

View File

@ -0,0 +1,56 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import com.ibm.wala.automaton.string.IAutomaton;
public abstract class AbstractPatternCompiler implements IPatternCompiler {
public IAutomaton compile(IPattern pattern) {
if (pattern instanceof IterationPattern) {
return onIteration((IterationPattern) pattern);
}
else if (pattern instanceof ComplementPattern) {
return onComplement((ComplementPattern) pattern);
}
else if (pattern instanceof ConcatenationPattern) {
return onConcatenation((ConcatenationPattern) pattern);
}
else if (pattern instanceof EmptyPattern) {
return onEmpty((EmptyPattern) pattern);
}
else if (pattern instanceof IntersectionPattern) {
return onIntersection((IntersectionPattern) pattern);
}
else if (pattern instanceof SymbolPattern) {
return onSymbol((SymbolPattern) pattern);
}
else if (pattern instanceof UnionPattern) {
return onUnion((UnionPattern) pattern);
}
else if (pattern instanceof VariableBindingPattern) {
return onVariableBinding((VariableBindingPattern) pattern);
}
else if (pattern instanceof VariableReferencePattern) {
return onVariableReference((VariableReferencePattern) pattern);
}
throw(new AssertionError("unknown type: " + pattern.getClass()));
}
public abstract IAutomaton onComplement(ComplementPattern pattern);
public abstract IAutomaton onConcatenation(ConcatenationPattern pattern);
public abstract IAutomaton onEmpty(EmptyPattern pattern);
public abstract IAutomaton onIntersection(IntersectionPattern pattern);
public abstract IAutomaton onIteration(IterationPattern pattern);
public abstract IAutomaton onSymbol(SymbolPattern pattern);
public abstract IAutomaton onUnion(UnionPattern pattern);
public abstract IAutomaton onVariableBinding(VariableBindingPattern pattern);
public abstract IAutomaton onVariableReference(VariableReferencePattern pattern);
}

View File

@ -0,0 +1,19 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import com.ibm.wala.automaton.string.Symbol;
public class CharPatternSymbol extends Symbol {
public CharPatternSymbol(String name) {
super(name);
}
}

View File

@ -0,0 +1,48 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
public class ComplementPattern extends AbstractPattern implements IPattern {
private IPattern pattern;
public ComplementPattern(IPattern pattern) {
this.pattern = pattern;
}
public IPattern getPattern() {
return pattern;
}
public int hashCode() {
return toString().hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
ComplementPattern p = (ComplementPattern) obj;
return pattern.equals(p.getPattern());
}
public String toString() {
return "!(" + pattern.toString() + ")";
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
pattern.traverse(visitor);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
return copier.copy(this, null);
}
}

View File

@ -0,0 +1,61 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.ArrayList;
import java.util.List;
public class ConcatenationPattern extends AbstractPattern implements IPattern {
private IPattern head;
private IPattern tail;
public ConcatenationPattern(IPattern head, IPattern tail) {
this.head = head;
this.tail = tail;
}
public IPattern getHead() {
return head;
}
public IPattern getTail() {
return tail;
}
public int hashCode() {
return head.hashCode() + tail.hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
ConcatenationPattern p = (ConcatenationPattern) obj;
return head.equals(p.getHead()) && tail.equals(p.getTail());
}
public String toString() {
return head.toString() + "." + tail.toString();
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
head.traverse(visitor);
tail.traverse(visitor);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
List l = new ArrayList();
l.add(head.copy(copier));
l.add(tail.copy(copier));
return copier.copy(this, l);
}
}

View File

@ -0,0 +1,41 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
public class EmptyPattern extends AbstractPattern implements IPattern {
public EmptyPattern() {
}
public int hashCode() {
return toString().hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
//EmptyPattern p = (EmptyPattern) obj;
return true;
}
public String toString() {
return "()";
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
return copier.copy(this, null);
}
}

View File

@ -0,0 +1,16 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
public interface IPattern extends Cloneable {
void traverse(IPatternVisitor visitor);
IPattern copy(IPatternCopier copier);
}

View File

@ -0,0 +1,26 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import com.ibm.wala.automaton.string.IAutomaton;
public interface IPatternCompiler {
IAutomaton compile(IPattern pattern);
IAutomaton onComplement(ComplementPattern pattern);
IAutomaton onConcatenation(ConcatenationPattern pattern);
IAutomaton onEmpty(EmptyPattern pattern);
IAutomaton onIntersection(IntersectionPattern pattern);
IAutomaton onIteration(IterationPattern pattern);
IAutomaton onSymbol(SymbolPattern pattern);
IAutomaton onUnion(UnionPattern pattern);
IAutomaton onVariableBinding(VariableBindingPattern pattern);
IAutomaton onVariableReference(VariableReferencePattern pattern);
}

View File

@ -0,0 +1,17 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.List;
public interface IPatternCopier {
IPattern copy(IPattern pattern, List children);
}

View File

@ -0,0 +1,16 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
public interface IPatternVisitor {
void onVisit(IPattern regex);
void onLeave(IPattern regex);
}

View File

@ -0,0 +1,61 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.ArrayList;
import java.util.List;
public class IntersectionPattern extends AbstractPattern implements IPattern {
private IPattern left;
private IPattern right;
public IntersectionPattern(IPattern left, IPattern right) {
this.left = left;
this.right = right;
}
public IPattern getLeft() {
return left;
}
public IPattern getRight() {
return right;
}
public int hashCode() {
return left.hashCode() + right.hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
IntersectionPattern p = (IntersectionPattern) obj;
return left.equals(p.getLeft()) && right.equals(p.getRight());
}
public String toString() {
return "(" + left.toString() + "&" + right.toString() + ")";
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
left.traverse(visitor);
right.traverse(visitor);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
List l = new ArrayList();
l.add(left.copy(copier));
l.add(right.copy(copier));
return copier.copy(this, l);
}
}

View File

@ -0,0 +1,64 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.ArrayList;
import java.util.List;
public class IterationPattern extends AbstractPattern implements IPattern {
private IPattern pattern;
private boolean empty;
public IterationPattern(IPattern pattern, boolean empty) {
this.pattern = pattern;
this.empty = empty;
}
public IterationPattern(IPattern pattern) {
this(pattern, true);
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
pattern.traverse(visitor);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
List l = new ArrayList();
l.add(pattern.copy(copier));
return copier.copy(this, l);
}
public IPattern getPattern() {
return pattern;
}
public boolean includesEmpty() {
return empty;
}
public int hashCode() {
return toString().hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
IterationPattern p = (IterationPattern) obj;
return pattern.equals(p.getPattern()) && empty==p.includesEmpty();
}
public String toString() {
return "(" + pattern.toString() + ")" + (empty ? "*" : "+");
}
}

View File

@ -0,0 +1,53 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import com.ibm.wala.automaton.string.*;
public class PatternCompiler extends AbstractPatternCompiler {
public IAutomaton onComplement(ComplementPattern pattern) {
return null;
}
public IAutomaton onConcatenation(ConcatenationPattern pattern) {
return null;
}
public IAutomaton onEmpty(EmptyPattern pattern) {
return null;
}
public IAutomaton onIntersection(IntersectionPattern pattern) {
return null;
}
public IAutomaton onIteration(IterationPattern pattern) {
return null;
}
public IAutomaton onSymbol(SymbolPattern pattern) {
return null;
}
public IAutomaton onUnion(UnionPattern pattern) {
return null;
}
public IAutomaton onVariableBinding(VariableBindingPattern pattern) {
return null;
}
public IAutomaton onVariableReference(VariableReferencePattern pattern) {
return null;
}
}

View File

@ -0,0 +1,86 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.*;
import com.ibm.wala.automaton.string.*;
public class StringPatternCompiler extends AbstractPatternCompiler {
static public final Set<CharSymbol> allChars = new HashSet<CharSymbol>();
static {
for (char c = 0; c < 255; c++) {
allChars.add(new CharSymbol(c));
}
}
public IAutomaton onComplement(ComplementPattern pattern) {
return Automatons.createComplement(compile(pattern.getPattern()), allChars);
}
public IAutomaton onConcatenation(ConcatenationPattern pattern) {
return Automatons.createConcatenation(
compile(pattern.getHead()),
compile(pattern.getTail()));
}
public IAutomaton onEmpty(EmptyPattern pattern) {
return Automatons.createAutomaton(new ISymbol[0]);
}
public IAutomaton onIntersection(IntersectionPattern pattern) {
return Automatons.createIntersection(
compile(pattern.getLeft()),
compile(pattern.getRight()));
}
public IAutomaton onIteration(IterationPattern pattern) {
IAutomaton a = compile(pattern.getPattern());
IState initState = a.getInitialState();
for (Iterator i = a.getFinalStates().iterator(); i.hasNext(); ) {
IState finState = (IState) i.next();
ITransition t = new Transition(finState, initState, Transition.EpsilonSymbol);
a.getTransitions().add(t);
}
if (pattern.includesEmpty()) {
a.getFinalStates().clear();
a.getFinalStates().add(initState);
}
return a;
}
public IAutomaton onSymbol(SymbolPattern pattern) {
ISymbol s = pattern.getSymbol();
if ((s instanceof CharPatternSymbol) && s.getName().equals("\\.")) {
return Automatons.createAutomaton(new ISymbol[]{new Variable(".")});
}
else {
return Automatons.createAutomaton(new ISymbol[]{s});
}
}
public IAutomaton onUnion(UnionPattern pattern) {
return Automatons.createUnion(
compile(pattern.getLeft()),
compile(pattern.getRight()));
}
public IAutomaton onVariableBinding(VariableBindingPattern pattern) {
// TODO: implement this method
return compile(pattern.getPattern());
}
public IAutomaton onVariableReference(VariableReferencePattern pattern) {
// TODO: implement this method
return null;
}
}

View File

@ -0,0 +1,185 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.List;
import com.ibm.wala.automaton.AUtil;
import com.ibm.wala.automaton.grammar.string.*;
import com.ibm.wala.automaton.parser.AmtParser;
import com.ibm.wala.automaton.string.*;
public class StringPatternSymbol implements ISymbol {
final static public IPatternCompiler defaultCompiler = new StringPatternCompiler();
final static private AmtParser parser = new AmtParser();
IPattern pattern;
IAutomaton compiledPattern;
IPatternCompiler compiler;
public StringPatternSymbol(IPattern pattern, IPatternCompiler compiler) {
if (pattern == null) throw(new AssertionError("should not be null."));
this.pattern = pattern;
this.compiler = compiler;
this.compiledPattern = compiler.compile(pattern);
}
public StringPatternSymbol(IPattern pattern) {
this(pattern, defaultCompiler);
}
public StringPatternSymbol(String pattern) {
this((IPattern) parser.parse("/" + pattern + "/").get(new Variable("_")));
}
public IAutomaton getCompiledPattern() {
return compiledPattern;
}
public IPattern getPattern() {
return pattern;
}
public String getName() {
return pattern.toString();
}
// TODO: should improve StringPatternSymbol#matches().
public boolean matches(ISymbol symbol, IMatchContext context) {
if (symbol instanceof StringPatternSymbol) {
StringPatternSymbol sps = (StringPatternSymbol) symbol;
IContextFreeGrammar cfg = Grammars.toCFG(sps.compiledPattern);
if (CFLReachability.containsAll(compiledPattern, cfg)) {
context.put(this, sps);
return true;
}
else {
return false;
}
}
else if (symbol instanceof StringSymbol) {
StringSymbol strSym = (StringSymbol) symbol;
List cs = strSym.toCharSymbols();
if (compiledPattern.accept(cs)) {
context.put(this, symbol);
return true;
}
else {
return false;
}
}
else if (symbol instanceof CFGSymbol) {
CFGSymbol cfgSymbol = (CFGSymbol) symbol;
if (CFLReachability.containsAll(compiledPattern, cfgSymbol.getGrammar())) {
context.put(this, symbol);
return true;
}
else {
return false;
}
}
else {
if (compiledPattern.accept(AUtil.list(new ISymbol[]{symbol}))) {
context.put(this, symbol);
return true;
}
else {
return false;
}
}
}
public boolean possiblyMatches(ISymbol symbol, IMatchContext context) {
if (symbol instanceof StringPatternSymbol) {
StringPatternSymbol sps = (StringPatternSymbol) symbol;
IContextFreeGrammar cfg = Grammars.toCFG(sps.compiledPattern);
if (CFLReachability.containsSome(cfg, compiledPattern)) {
context.put(this, sps);
return true;
}
else {
return false;
}
}
else if (symbol instanceof StringSymbol) {
StringSymbol strSym = (StringSymbol) symbol;
List cs = strSym.toCharSymbols();
if (compiledPattern.accept(cs)) {
context.put(this, symbol);
return true;
}
else {
return false;
}
}
else if (symbol instanceof CFGSymbol) {
CFGSymbol cfgSymbol = (CFGSymbol) symbol;
if (CFLReachability.containsSome(cfgSymbol.getGrammar(), compiledPattern)) {
context.put(this, symbol);
return true;
}
else {
return false;
}
}
else {
if (compiledPattern.accept(AUtil.list(new ISymbol[]{symbol}))) {
context.put(this, symbol);
return true;
}
else {
return false;
}
}
}
public int hashCode() {
return pattern.hashCode() + compiledPattern.hashCode() + compiler.hashCode();
}
public boolean equals(Object obj) {
if (!getClass().equals(obj.getClass())) return false;
StringPatternSymbol ps = (StringPatternSymbol) obj;
return pattern.equals(ps.pattern)
&& compiledPattern.equals(ps.compiledPattern)
&& compiler.equals(compiler);
}
public void traverse(ISymbolVisitor visitor) {
visitor.onVisit(this);
visitor.onLeave(this);
}
public ISymbol copy(ISymbolCopier copier) {
ISymbol s = copier.copy(this);
if (s instanceof StringPatternSymbol) {
StringPatternSymbol ps = (StringPatternSymbol) s;
if (copier instanceof ISTSCopier) {
ISTSCopier scopier = (ISTSCopier) copier;
ps.compiledPattern = (IAutomaton) scopier.copy(ps.compiledPattern);
}
}
return s;
}
public int size() {
return 0;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw(new RuntimeException(e));
}
}
}

View File

@ -0,0 +1,79 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import com.ibm.wala.automaton.string.*;
public class SymbolPattern extends AbstractPattern implements IPattern {
private ISymbol symbol;
public SymbolPattern(ISymbol symbol) {
this.symbol = symbol;
}
public SymbolPattern(String symbol) {
this(new StringSymbol(symbol));
}
public ISymbol getSymbol() {
return symbol;
}
public int hashCode() {
return symbol.hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
SymbolPattern p = (SymbolPattern) obj;
return getSymbol().equals(p.getSymbol());
}
public String toString() {
return symbol.toString();
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
return copier.copy(this, null);
}
static public IPattern toCharSequencePattern(char cs[]){
IPattern pat = null;
for (int i = cs.length-1; i >= 0; i--) {
SymbolPattern sp = new SymbolPattern(Character.toString(cs[i]));
if (pat == null) {
pat = sp;
}
else {
pat = new ConcatenationPattern(sp, pat);
}
}
return pat;
}
static public IPattern toCharSequencePattern(SymbolPattern symp){
return toCharSequencePattern(symp.getSymbol().getName().toCharArray());
}
static public IPattern toCharSequencePattern(String str) {
return toCharSequencePattern(str.toCharArray());
}
public IPattern toCharSequencePattern() {
return toCharSequencePattern(this);
}
}

View File

@ -0,0 +1,62 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.ArrayList;
import java.util.List;
public class UnionPattern extends AbstractPattern implements IPattern {
private IPattern left;
private IPattern right;
public UnionPattern(IPattern left, IPattern right) {
this.left = left;
this.right = right;
}
public IPattern getLeft() {
return left;
}
public IPattern getRight() {
return right;
}
public int hashCode() {
return left.hashCode() + right.hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
UnionPattern p = (UnionPattern) obj;
return left.equals(p.getLeft()) && right.equals(p.getRight());
}
public String toString() {
return left.toString() + "|" + right.toString();
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
left.traverse(visitor);
right.traverse(visitor);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
List l = new ArrayList();
l.add(left.copy(copier));
l.add(right.copy(copier));
return copier.copy(this, l);
}
}

View File

@ -0,0 +1,65 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import java.util.ArrayList;
import java.util.List;
import com.ibm.wala.automaton.string.IVariable;
public class VariableBindingPattern extends AbstractPattern implements IPattern {
private IVariable variable;
private IPattern pattern;
public VariableBindingPattern(IPattern pattern, IVariable variable) {
this.pattern = pattern;
this.variable = variable;
}
public VariableBindingPattern(IVariable variable, IPattern pattern) {
this(pattern, variable);
}
public IPattern getPattern() {
return pattern;
}
public IVariable getVariable() {
return variable;
}
public int hashCode() {
return pattern.hashCode() + variable.hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
VariableBindingPattern p = (VariableBindingPattern) obj;
return pattern.equals(p.getPattern()) && variable.equals(p.getVariable());
}
public String toString() {
return "(" + pattern.toString() + " as " + variable.toString() + ")";
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
pattern.traverse(visitor);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
List l = new ArrayList();
l.add(pattern.copy(copier));
return copier.copy(this, l);
}
}

View File

@ -0,0 +1,49 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.string;
import com.ibm.wala.automaton.string.*;
public class VariableReferencePattern extends AbstractPattern implements IPattern {
private IVariable variable;
public VariableReferencePattern(IVariable variable) {
this.variable = variable;
}
public IVariable getVariable() {
return variable;
}
public int hashCode() {
return variable.hashCode();
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!getClass().equals(obj.getClass())) return false;
VariableReferencePattern p = (VariableReferencePattern) obj;
return variable.equals(p.getVariable());
}
public String toString() {
return "ref" + variable.toString();
}
public void traverse(IPatternVisitor visitor) {
visitor.onVisit(this);
visitor.onLeave(this);
}
public IPattern copy(IPatternCopier copier) {
return copier.copy(this, null);
}
}

View File

@ -0,0 +1,17 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.tree;
import com.ibm.wala.automaton.regex.string.IPattern;
public interface ITreePattern extends IPattern {
}

View File

@ -0,0 +1,16 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.regex.tree;
import com.ibm.wala.automaton.regex.string.*;
public class TreePatternCompiler extends PatternCompiler {
}

View File

@ -0,0 +1,63 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Collection;
import java.util.Iterator;
public abstract class AbstractStateCopier implements IStateCopier {
public IState copy(IState state) {
if (state == null) {
return null;
}
else {
return (IState) state.clone();
}
}
public Collection copyStates(Collection states) {
try {
Collection c = (Collection) states.getClass().newInstance();
for (Iterator i = states.iterator(); i.hasNext(); ) {
IState s = (IState) i.next();
c.add(s.copy(this));
}
return c;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw(new AssertionError("should not reach this code."));
}
public abstract String copyStateName(String name);
public abstract IState copyStateReference(IState parent, IState state);
public Collection copyStateReferences(IState parent, Collection states) {
try {
Collection c = (Collection) states.getClass().newInstance();
for (Iterator i = states.iterator(); i.hasNext(); ) {
IState s = (IState) i.next();
c.add(copyStateReference(parent, s));
}
return c;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw(new AssertionError("should not reach this code."));
}
}

View File

@ -0,0 +1,64 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
abstract public class AbstractSymbolCopier implements ISymbolCopier {
public ISymbol copy(ISymbol symbol) {
if (symbol == null) {
return null;
}
else {
return (ISymbol) symbol.clone();
}
}
public Collection copySymbols(Collection symbols) {
Collection c;
try {
c = (Collection) symbols.getClass().newInstance();
for (Iterator i = symbols.iterator(); i.hasNext(); ) {
ISymbol s = (ISymbol) i.next();
c.add(s.copy(this));
}
return c;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw(new AssertionError("should not reach this code."));
}
abstract public String copyName(String name);
abstract public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol);
public Collection copySymbolReferences(ISymbol parent, Collection symbols) {
Collection c;
try {
c = (Collection) symbols.getClass().newInstance();
for (Iterator i = symbols.iterator(); i.hasNext(); ) {
ISymbol s = (ISymbol) i.next();
c.add(copySymbolReference(parent, s));
}
return c;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw(new AssertionError("should not reach this code."));
}
}

View File

@ -0,0 +1,29 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Collection;
import com.ibm.wala.automaton.AUtil;
public abstract class AbstractTransitionCopier implements ITransitionCopier {
public abstract ITransition copy(ITransition transition);
public Collection copyTransitions(Collection transitions) {
return AUtil.collect(transitions, new AUtil.IElementMapper(){
public Object map(Object obj) {
ITransition t = (ITransition) obj;
return t.copy(AbstractTransitionCopier.this);
}
});
}
}

View File

@ -0,0 +1,166 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
import com.ibm.wala.automaton.*;
public class Automaton extends StateTransitionSystem implements IAutomaton {
private Set finalStates;
public Automaton(IState initialState, Set finalStates, Set transitions){
super(initialState, transitions);
this.finalStates = new HashSet(finalStates);
}
public Automaton(IState initialState, IState[] finalStates, ITransition[] transitions) {
super(initialState, transitions);
this.finalStates = AUtil.set(finalStates);
}
public Automaton(IAutomaton automaton) {
this(automaton.getInitialState(), automaton.getFinalStates(), automaton.getTransitions());
}
public Automaton(){
super();
finalStates = new HashSet();
}
public Set getFinalStates() {
return finalStates;
}
public Set getStates() {
Set states = super.getStates();
states.addAll(finalStates);
return states;
}
private boolean isFinalState(IState state){
return getFinalStates().contains(state);
}
public List translate(List symbols) {
return translate(getInitialState(), symbols);
}
public boolean accept(List symbols) {
return accept(getInitialState(), symbols);
}
public boolean accept(IState state, List symbols){
return !translate(state, symbols).isEmpty();
}
protected List translate(IState state, List symbols){
if (symbols.isEmpty()) {
if (isFinalState(state)) {
List l = new ArrayList();
l.add(new ArrayList());
return l;
}
}
List output = new ArrayList();
Set epsilons = getEpsilonTransitions(state);
for (Iterator i = epsilons.iterator(); i.hasNext(); ) {
ITransition transition = (ITransition) i.next();
if (transition.getPostState().equals(state)) {
continue;
}
List results = null;
results = translate(transition.getPostState(), symbols);
if (results != null) {
for (Iterator j = results.iterator(); j.hasNext(); ) {
List l = (List) j.next();
l.addAll(0, AUtil.list(transition.getOutputSymbols()));
}
output.addAll(results);
}
}
if (symbols.isEmpty()) {
if (output.isEmpty()) {
return new ArrayList();
}
else {
return output;
}
}
List tail = new ArrayList(symbols);
ISymbol symbol = (ISymbol) tail.get(0);
tail.remove(0);
Set transitions = getAcceptTransitions(state, symbol);
for (Iterator i = transitions.iterator(); i.hasNext(); ) {
ITransition transition = (ITransition) i.next();
List results = null;
results = translate(transition.getPostState(), tail);
if (results != null) {
for (Iterator j = results.iterator(); j.hasNext(); ) {
List l = (List) j.next();
l.addAll(0, transition.transit(symbol));
}
output.addAll(results);
}
}
return output;
}
public void traverseStates(final IStateVisitor visitor) {
super.traverseStates(visitor);
for (Iterator i = getFinalStates().iterator(); i.hasNext(); ) {
IState state = (IState) i.next();
visitor.onVisit(state);
}
}
public boolean equals(Object obj) {
if (super.equals(obj)) {
Automaton a = (Automaton) obj;
return finalStates.equals(a.finalStates);
}
else {
return false;
}
}
public IStateTransitionSystem copy(ISTSCopier copier) {
Automaton a = (Automaton) super.copy(copier);
a.finalStates = new HashSet(copier.copyStates(a.finalStates));
return a;
}
public String toString() {
StringBuffer transitions = new StringBuffer();
for (Iterator i = AUtil.sort(getTransitions()).iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
transitions.append(t.toString());
if (i.hasNext()) {
transitions.append(", ");
}
}
StringBuffer finalStates = new StringBuffer();
for (Iterator i = getFinalStates().iterator(); i.hasNext(); ) {
IState state = (IState) i.next();
finalStates.append(state.toString());
if (i.hasNext()) {
finalStates.append("; ");
}
}
return "{init:" + getInitialState() + ", final:{" + finalStates + "}, transitions:{" + transitions + "}}";
}
}

View File

@ -0,0 +1,716 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
import com.ibm.wala.automaton.*;
import com.ibm.wala.automaton.regex.string.*;
import com.ibm.wala.automaton.tree.CompositeState;
public class Automatons {
static public String prefixState = "s";
static public String prefixInputSymbol = "i";
static public String createUniqueStateName(IAutomaton automaton) {
final Set states = new HashSet();
automaton.traverseStates(new IStateVisitor(){
public void onVisit(IState state) {
states.add(state.getName());
}
});
return AUtil.createUniqueName(prefixState, states);
}
static public String createUniqueInputSymbolName(IAutomaton automaton) {
final Set symbols = new HashSet();
automaton.traverseTransitions(new ITransitionVisitor(){
public void onVisit(ITransition transition) {
ISymbol sym = transition.getInputSymbol();
if (sym != null) {
symbols.add(sym.getName());
}
}
});
return AUtil.createUniqueName(prefixInputSymbol, symbols);
}
static public IState createUniqueState(IAutomaton automaton) {
return new State(createUniqueStateName(automaton));
}
static public ISymbol createUniqueInputSymbol(IAutomaton automaton) {
return new Symbol(createUniqueInputSymbolName(automaton));
}
static public Set collectStateNames(Set states) {
return new HashSet(AUtil.collect(states, new AUtil.IElementMapper(){
public Object map(Object obj) {
return ((IState)obj).getName();
}
}));
}
static public Set collectStateNames(IAutomaton automaton) {
return collectStateNames(automaton.getStates());
}
static public Set collectInputSymbols(IAutomaton automaton) {
final Set symbols = new HashSet();
automaton.traverseTransitions(new ITransitionVisitor(){
public void onVisit(ITransition transition) {
if (!transition.isEpsilonTransition()) {
ISymbol s = transition.getInputSymbol();
symbols.add(s);
}
}
});
return symbols;
}
static public Set collectInputSymbolNames(Set symbols) {
return new HashSet(AUtil.collect(symbols, new AUtil.IElementMapper(){
public Object map(Object obj) {
return ((ISymbol)obj).getName();
}
}));
}
static public Set collectInputSymbolNames(IAutomaton automaton) {
return collectInputSymbolNames(collectInputSymbols(automaton));
}
static public IAutomaton useUniqueStates(IAutomaton target, IAutomaton base, Map stateMap) {
Set baseNames = collectStateNames(base);
return useUniqueStates(target, baseNames, stateMap);
}
static public IAutomaton useUniqueStates(IAutomaton target, Set baseNames, Map stateMap) {
final Map map = (stateMap==null) ? new HashMap() : stateMap;
Set states = target.getStates();
for (Iterator i = states.iterator(); i.hasNext(); ) {
IState s = (IState) i.next();
String n = AUtil.createUniqueName(prefixState, baseNames);
IState u = new State(n);
map.put(s, u);
}
final Set newTransitions = new HashSet();
target.traverseTransitions(new ITransitionVisitor(){
public void onVisit(ITransition transition) {
IState preState = (IState) map.get(transition.getPreState());
IState postState = (IState) map.get(transition.getPostState());
ITransition newTransition = transition.copy(SimpleTransitionCopier.defaultCopier);
newTransition.setPreState(preState);
newTransition.setPostState(postState);
newTransitions.add(newTransition);
}
});
IState initState = (IState) map.get(target.getInitialState());
Set finalStates = new HashSet(AUtil.collect(target.getFinalStates(), new AUtil.IElementMapper(){
public Object map(Object obj) {
IState s = (IState) map.get(obj);
return s;
}
}));
// TODO: should use Automaton#copy
IAutomaton result = new Automaton(initState, finalStates, newTransitions);
return result;
}
static public IAutomaton useUniqueInputSymbols(IAutomaton target, IAutomaton base, Map symMap) {
Set baseNames = collectInputSymbolNames(base);
return useUniqueInputSymbols(target, baseNames, symMap);
}
static public IAutomaton useUniqueInputSymbols(IAutomaton target, Set baseNames, Map symMap) {
final Map map = (symMap==null) ? new HashMap() : symMap;
Set symbols = collectInputSymbols(target);
for (Iterator i = symbols.iterator(); i.hasNext(); ) {
ISymbol s = (ISymbol) i.next();
String n = AUtil.createUniqueName("i", baseNames);
ISymbol u = new Symbol(n);
map.put(s, u);
}
final Set newTransitions = new HashSet();
target.traverseTransitions(new ITransitionVisitor(){
public void onVisit(ITransition transition) {
if (transition.getInputSymbol() instanceof IVariable) {
newTransitions.add(transition);
}
else {
ISymbol isym = (ISymbol) map.get(transition.getInputSymbol());
ITransition newTransition = transition.copy(SimpleTransitionCopier.defaultCopier);
newTransition.setInputSymbol(isym);
newTransitions.add(newTransition);
}
}
});
IState initState = target.getInitialState();
Set finalStates = target.getFinalStates();
// TODO: should use Automaton#copy
IAutomaton result = new Automaton(initState, finalStates, newTransitions);
return result;
}
static public IAutomaton createConcatenation(IAutomaton automaton1, IAutomaton automaton2, Map stateMap) {
automaton2 = useUniqueStates(automaton2, automaton1, stateMap);
IAutomaton result = (IAutomaton) automaton1.copy(SimpleSTSCopier.defaultCopier);
createSimpleConcatenation(result, automaton2);
return result;
}
static public IAutomaton createConcatenation(IAutomaton automaton1, IAutomaton automaton2) {
return createConcatenation(automaton1, automaton2, new HashMap());
}
static public void createSimpleConcatenation(IAutomaton automaton1, IAutomaton automaton2) {
IState initState2 = automaton2.getInitialState();
Set finalStates1 = automaton1.getFinalStates();
for (Iterator i = finalStates1.iterator(); i.hasNext(); ) {
IState finalState1 = (IState) i.next();
if (finalState1.equals(initState2)) {
continue ;
}
ITransition newTransition = new Transition(finalState1, initState2);
automaton1.getTransitions().add(newTransition);
}
automaton1.getTransitions().addAll(automaton2.getTransitions());
automaton1.getFinalStates().clear();
automaton1.getFinalStates().addAll(automaton2.getFinalStates());
}
static public IAutomaton createUnion(IAutomaton automaton1, IAutomaton automaton2, Map stateMap) {
automaton2 = useUniqueStates(automaton2, automaton1, stateMap);
IAutomaton result = (IAutomaton) automaton1.copy(SimpleSTSCopier.defaultCopier);
createSimpleUnion(result, automaton2);
return result;
}
static public void createSimpleUnion(IAutomaton automaton1, IAutomaton automaton2) {
automaton1.getFinalStates().addAll(automaton2.getFinalStates());
automaton1.getTransitions().addAll(automaton2.getTransitions());
List stateNames = AUtil.collect(automaton1.getStates(), new AUtil.IElementMapper(){
public Object map(Object obj) {
IState state = (IState) obj;
return state.getName();
}}
);
IState initState = new State(AUtil.createUniqueName("s", stateNames));
IState initState1 = automaton1.getInitialState();
IState initState2 = automaton2.getInitialState();
ITransition transition1 = new Transition(initState, initState1);
ITransition transition2 = new Transition(initState, initState2);
automaton1.setInitialState(initState);
automaton1.getTransitions().add(transition1);
automaton1.getTransitions().add(transition2);
}
static public IAutomaton createUnion(IAutomaton automaton1, IAutomaton automaton2) {
return createUnion(automaton1, automaton2, new HashMap());
}
static public void completeAutomaton(IAutomaton automaton, IState failState, IVariable v, List outputSymbols, FilteredTransition.IFilter filter) {
// eliminateEpsilonTransitions(automaton);
Set stateNames = collectStateNames(automaton);
stateNames.add(failState.getName());
eliminateNonDeterministics(automaton, stateNames);
Set states = automaton.getStates();
Set newTransitions = new HashSet();
for (Iterator i = states.iterator(); i.hasNext(); ) {
IState s = (IState) i.next();
Set nextTransitions = automaton.getTransitions(s);
ITransition complement = new ComplementTransition(s, failState, v, outputSymbols, filter, nextTransitions);
newTransitions.add(complement);
}
automaton.getTransitions().addAll(newTransitions);
}
static public IAutomaton createComplement(IAutomaton automaton, IState failState, IVariable v, FilteredTransition.IFilter filter) {
IAutomaton ca = (IAutomaton) automaton.copy(SimpleSTSCopier.defaultCopier);
completeAutomaton(ca, failState, v, AUtil.list(new ISymbol[]{}), filter);
ITransition t = new FilteredTransition(failState, failState, v, new ISymbol[]{}, filter);
Set finalStates = new HashSet(ca.getStates());
finalStates.add(failState);
finalStates.removeAll(ca.getFinalStates());
ca.getTransitions().add(t);
ca.getFinalStates().clear();
ca.getFinalStates().addAll(finalStates);
return ca;
}
static public IAutomaton createComplement(IAutomaton automaton, Set symbols) {
return createComplement(expand(automaton, symbols));
}
static public IAutomaton createComplement(IAutomaton automaton, Set symbols, IState failState) {
return createComplement(expand(automaton, symbols), failState);
}
static public IAutomaton createComplement(IAutomaton automaton, IState failState) {
return createComplement(automaton, failState, new Variable("_"), null);
}
static public IAutomaton createComplement(IAutomaton automaton) {
return createComplement(automaton, createUniqueState(automaton));
}
static public IAutomaton createIntersection(IAutomaton automaton1, IAutomaton automaton2) {
automaton1 = (IAutomaton) automaton1.copy(SimpleSTSCopier.defaultCopier);
automaton2 = (IAutomaton) automaton2.copy(SimpleSTSCopier.defaultCopier);
Automatons.eliminateEpsilonTransitions(automaton1);
Automatons.eliminateEpsilonTransitions(automaton2);
final Set transitions = new HashSet();
final DMap map = new DMap(new DMap.Factory(){
private Set names = new HashSet();
public Object create(Object key) {
String name = AUtil.createUniqueName("s", names);
return new State(name);
}
});
for (Iterator i = automaton1.getTransitions().iterator(); i.hasNext(); ) {
ITransition t1 = (ITransition) i.next();
for (Iterator j = automaton2.getTransitions().iterator(); j.hasNext(); ) {
ITransition t2 = (ITransition) j.next();
IMatchContext ctx = new MatchContext();
ISymbol input1 = t1.getInputSymbol();
ISymbol input2 = t2.getInputSymbol();
if (input1 instanceof IVariable || input2 instanceof IVariable) {
CompositeState pre = new CompositeState("s", new IState[]{t1.getPreState(), t2.getPreState()});
CompositeState post = new CompositeState("s", new IState[]{t1.getPostState(), t2.getPostState()});
IntersectionTransition.IFilter filter1 = null;
IntersectionTransition.IFilter filter2 = null;
if (t1 instanceof FilteredTransition) {
filter1 = ((FilteredTransition)t1).getFilter();
}
if (t2 instanceof FilteredTransition) {
filter2 = ((FilteredTransition)t2).getFilter();
}
Transition ta = new IntersectionTransition((IState)map.get(pre), (IState)map.get(post), t1.getInputSymbol(), t1.getOutputSymbols(), filter1, new ITransition[]{t1, t2});
transitions.add(ta);
Transition tb = new IntersectionTransition((IState)map.get(pre), (IState)map.get(post), t2.getInputSymbol(), t2.getOutputSymbols(), filter2, new ITransition[]{t1, t2});
transitions.add(tb);
}
else if (input1.matches(input2, ctx)) {
CompositeState pre = new CompositeState("s", new IState[]{t1.getPreState(), t2.getPreState()});
CompositeState post = new CompositeState("s", new IState[]{t1.getPostState(), t2.getPostState()});
if (t1.hasOutputSymbols() || t2.hasOutputSymbols()) {
Transition ta = new Transition((IState)map.get(pre), (IState)map.get(post), t2.getInputSymbol(), t1.getOutputSymbols());
transitions.add(ta);
Transition tb = new Transition((IState)map.get(pre), (IState)map.get(post), t2.getInputSymbol(), t1.getOutputSymbols());
transitions.add(tb);
}
else {
Transition t = new Transition((IState)map.get(pre), (IState)map.get(post), t2.getInputSymbol());
transitions.add(t);
}
}
else if (input2.matches(input1, ctx)) {
CompositeState pre = new CompositeState("s", new IState[]{t1.getPreState(), t2.getPreState()});
CompositeState post = new CompositeState("s", new IState[]{t1.getPostState(), t2.getPostState()});
if (t1.hasOutputSymbols() || t2.hasOutputSymbols()) {
Transition ta = new Transition((IState)map.get(pre), (IState)map.get(post), t1.getInputSymbol(), t1.getOutputSymbols());
transitions.add(ta);
Transition tb = new Transition((IState)map.get(pre), (IState)map.get(post), t1.getInputSymbol(), t1.getOutputSymbols());
transitions.add(tb);
}
else {
Transition t = new Transition((IState)map.get(pre), (IState)map.get(post), t1.getInputSymbol());
transitions.add(t);
}
}
}
}
final IState initState = (IState) map.get(new CompositeState("s", new IState[]{automaton1.getInitialState(), automaton2.getInitialState()}));
final Set finalStates = new HashSet();
for (Iterator i = automaton1.getFinalStates().iterator(); i.hasNext(); ) {
IState f1 = (IState) i.next();
for (Iterator j = automaton2.getFinalStates().iterator(); j.hasNext(); ) {
IState f2 = (IState) j.next();
CompositeState cs = new CompositeState("s", new IState[]{f1, f2});
finalStates.add((IState)map.get(cs));
}
}
final IAutomaton origAutomaton1 = automaton1;
IAutomaton a = (IAutomaton) automaton1.copy(new SimpleSTSCopier(){
public Collection copyTransitions(Collection c) {
return transitions;
}
public IState copy(IState s) {
if (s == origAutomaton1.getInitialState()) {
return initState;
}
else {
return super.copy(s);
}
}
public Collection copyStates(Collection states) {
if (states == origAutomaton1.getFinalStates()) {
return finalStates;
}
else {
return super.copyStates(states);
}
}
});
return a;
}
public static IAutomaton createSubtraction(IAutomaton a1, IAutomaton a2) {
return createIntersection(a1, createComplement(a2));
}
public static IPattern toPattern(IAutomaton automaton) {
Set equations = createEquations(automaton);
return solvePatternEquations(equations, new Variable(automaton.getInitialState().getName()));
}
/**
* solve equations
* @param equations
* @return
*/
public static IPattern solvePatternEquations(Set equations, IVariable variable) {
// TODO: implement equation solver
throw(new AssertionError("equation solver is not implemented yet"));
}
private static Set createEquations(IAutomaton automaton) {
final Set equations = new HashSet();
automaton.traverseTransitions(new ITransitionVisitor(){
public void onVisit(ITransition transition) {
IVariable lhs = new Variable(transition.getPreState().getName());
IPattern rhs = null;
if (!transition.isEpsilonTransition()) {
SymbolPattern rhs1 = new SymbolPattern(transition.getInputSymbol());
VariableReferencePattern rhs2 = new VariableReferencePattern(new Variable(transition.getPostState().getName()));
rhs = new ConcatenationPattern(rhs1, rhs2);
}
else {
rhs = new VariableReferencePattern(new Variable(transition.getPostState().getName()));
}
VariableBindingPattern equation = new VariableBindingPattern(lhs, rhs);
equations.add(equation);
}
});
return equations;
}
public static Automaton createAutomaton(List symbols) {
ISymbol syms[] = new ISymbol[symbols.size()];
symbols.toArray(syms);
return createAutomaton(syms);
}
public static Automaton createAutomaton(ISymbol[] symbols) {
Set transitions = new HashSet();
Set finalStates = new HashSet();
int i = 0;
State initState = new State("s" + i);
State preState = initState;
while (i < symbols.length) {
State postState = new State("s" + i+1);
Transition trans = new Transition(preState, postState, symbols[i]);
transitions.add(trans);
preState = postState;
i++;
}
finalStates.add(preState);
Automaton automaton = new Automaton(initState, finalStates, transitions);
return automaton;
}
static public void eliminateUnreachableStates(IAutomaton automaton) {
Set reachableStates = collectReachableStates(automaton);
for (Iterator i = automaton.getTransitions().iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
if (!(reachableStates.contains(t.getPreState())
&& reachableStates.contains(t.getPostState()))) {
i.remove();
}
}
for (Iterator i = automaton.getFinalStates().iterator(); i.hasNext(); ) {
IState s = (IState) i.next();
if (!reachableStates.contains(s)) {
i.remove();
}
}
}
static public Set collectReachableStates(IAutomaton automaton) {
Set s = new HashSet();
collectReachableStates(automaton, automaton.getInitialState(), s);
return s;
}
static public void collectReachableStates(IAutomaton automaton, IState s, Set states) {
if (states.contains(s)) {
return ;
}
states.add(s);
for (Iterator i = automaton.getTransitions(s).iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
collectReachableStates(automaton, t.getPostState(), states);
}
}
static private void copyFinalStatesForEliminateEpsilonTransitions(IAutomaton automaton) {
int n = 0;
do {
n = 0;
for (Iterator i = automaton.getTransitions().iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
if (t.isEpsilonTransition() && automaton.getFinalStates().contains(t.getPostState())) {
if (t.hasOutputSymbols()) {
// TODO: should support this case.
throw(new AssertionError("unsupported operation"));
}
IState s = t.getPreState();
if (!automaton.getFinalStates().contains(s)) {
automaton.getFinalStates().add(s);
n ++;
}
}
}
} while (n != 0);
}
static public void eliminateEpsilonTransitions(IAutomaton automaton) {
copyFinalStatesForEliminateEpsilonTransitions(automaton);
Set epsTransitions = new HashSet();
for (Iterator i = automaton.getTransitions().iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
if (t.isEpsilonTransition()) {
if (t.getPreState().equals(t.getPostState())) {
i.remove();
}
else {
epsTransitions.add(t);
}
}
}
for (Iterator i = epsTransitions.iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
Set newTransitions = getNonEpsilonTransitions(automaton, t);
automaton.getTransitions().addAll(newTransitions);
}
automaton.getTransitions().removeAll(epsTransitions);
}
static public void eliminateEpsilonTransition(IAutomaton automaton, ITransition t) {
Set newTransitions = getNonEpsilonTransitions(automaton, t);
if (automaton.getFinalStates().contains(t.getPostState())) {
automaton.getFinalStates().add(t.getPreState());
}
automaton.getTransitions().remove(t);
automaton.getTransitions().addAll(newTransitions);
}
static private Set getNonEpsilonTransitions(IAutomaton automaton, ITransition transition) {
return getNonEpsilonTransitions(automaton, transition, transition.getPreState(), new ArrayList(), new HashSet());
}
static private Set getNonEpsilonTransitions(IAutomaton automaton, ITransition transition, IState state, List outputs, Set history) {
if (history.contains(transition)) {
return new HashSet();
}
history.add(transition);
Set result = new HashSet();
if (transition.isEpsilonTransition()) {
List l = new ArrayList(outputs);
l.addAll(AUtil.list(transition.getOutputSymbols()));
Set nextTransitions = automaton.getTransitions(transition.getPostState());
for (Iterator i = nextTransitions.iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
result.addAll(getNonEpsilonTransitions(automaton, t, state, l, history));
}
}
else {
ITransition newTransition = (ITransition) transition.clone();
newTransition.setPreState(state);
newTransition.prependOutputSymbols(outputs);
result.add(newTransition);
}
return result;
}
static public void eliminateNonDeterministics(IAutomaton automaton) {
eliminateNonDeterministics(automaton, null);
}
static public void eliminateNonDeterministics(IAutomaton automaton, Set stateNames) {
if (stateNames == null) {
stateNames = Automatons.collectStateNames(automaton);
}
eliminateEpsilonTransitions(automaton);
for (Iterator i = automaton.getStates().iterator(); i.hasNext(); ) {
IState state = (IState) i.next();
eliminateNonDeterministics(automaton, state, stateNames);
}
eliminateUnreachableStates(automaton);
}
static private void eliminateNonDeterministics(IAutomaton automaton, IState state, Set stateNames) {
Set transitions = automaton.getTransitions(state);
for (Iterator i = transitions.iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
if (t.getInputSymbol() instanceof IVariable) {
throw(new RuntimeException("can't handle the variable at the transition: " + t.getInputSymbol()));
}
if (t.hasOutputSymbols()) {
List<ISymbol> outs = new ArrayList<ISymbol>();
for (Iterator<ISymbol> o = t.getOutputSymbols(); o.hasNext(); ) {
ISymbol out = o.next();
outs.add(out);
}
throw(new RuntimeException("can't handle the output symbols at the transition: " + outs));
}
}
Set inputs = new HashSet(AUtil.collect(transitions, new AUtil.IElementMapper(){
public Object map(Object obj) {
return ((ITransition) obj).getInputSymbol();
}
}));
for (Iterator i = inputs.iterator(); i.hasNext(); ) {
ISymbol input = (ISymbol) i.next();
eliminateNonDeterministics(automaton, state, input, stateNames);
}
}
static private void eliminateNonDeterministics(IAutomaton automaton, IState state, ISymbol inputSymbol, Set stateNames) {
final Set removeTransitions = new HashSet();
final Set newTransitions = new HashSet();
Set sameTransitions = automaton.getTransitions(state, inputSymbol);
/*
AUtil.select(sameTransitions, new AUtil.IElementSelector(){
public boolean selected(Object obj) {
ITransition t = (ITransition) obj;
return AUtil.list(t.getOutputSymbols()).equals(outputSymbols);
}
});
*/
if (sameTransitions.size()<=1) return;
String newStateName = AUtil.createUniqueName("s", stateNames);
IState newState = new State(newStateName);
ITransition newTransition = new Transition(state, newState, inputSymbol);
removeTransitions.addAll(sameTransitions);
newTransitions.add(newTransition);
for (Iterator j = sameTransitions.iterator(); j.hasNext(); ) {
ITransition jt = (ITransition) j.next();
IState postState = jt.getPostState();
if (automaton.getFinalStates().contains(postState)) {
automaton.getFinalStates().add(newState);
}
if (postState.equals(state)) {
ITransition t = (ITransition) jt.clone();
t.setPreState(newState);
t.setPostState(newState);
newTransitions.add(t);
}
else {
for (Iterator k = automaton.getTransitions(postState).iterator(); k.hasNext(); ) {
ITransition kt = (ITransition) k.next();
ITransition newPostTransition = (ITransition) kt.clone();
kt.setPreState(newState);
newTransitions.add(newPostTransition);
}
}
}
HashSet ts = new HashSet(automaton.getTransitions());
ts.addAll(newTransitions);
ts.removeAll(removeTransitions);
automaton.getTransitions().clear();
automaton.getTransitions().addAll(ts);
for (Iterator i = newTransitions.iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
eliminateNonDeterministics(automaton, newState, t.getInputSymbol(), stateNames);
}
}
/**
* replace all the transitions of the automaton with the Transition object.
* @param automaton
* @param allSymbols
*/
static public IAutomaton expand(IAutomaton automaton, Set allSymbols) {
automaton = (IAutomaton) automaton.copy(SimpleSTSCopier.defaultCopier);
IMatchContext ctx = new MatchContext();
Set transitions = new HashSet();
for (Iterator i = automaton.getTransitions().iterator(); i.hasNext(); ) {
final ITransition t = (ITransition) i.next();
for (Iterator j = allSymbols.iterator(); j.hasNext(); ) {
ISymbol input = (ISymbol) j.next();
if (t.isEpsilonTransition()) {
transitions.add(t);
}
else if (t.accept(input, ctx)) {
final List outputs = t.transit(input);
Transition tt = new Transition(t.getPreState(), t.getPostState(), input, outputs);
transitions.add(tt);
}
}
}
automaton.getTransitions().clear();
automaton.getTransitions().addAll(transitions);
return automaton;
}
public interface IGraphvizLabelGenerator {
public String getLabel(ITransition t);
}
static public class SimpleGraphvizLabelGenerator implements IGraphvizLabelGenerator {
public String getLabel(ITransition t) {
return t.getInputSymbol() + "/" + AUtil.list(t.getOutputSymbols());
}
}
static public String toGraphviz(IAutomaton automaton) {
return toGraphviz(automaton, new SimpleGraphvizLabelGenerator());
}
static public String toGraphviz(IAutomaton automaton, IGraphvizLabelGenerator labelGenerator) {
StringBuffer buff = new StringBuffer();
buff.append("digraph G {");
buff.append(AUtil.lineSeparator);
buff.append(" \"\" [fillcolor=black, shape=point]");
buff.append(AUtil.lineSeparator);
buff.append(" \"\" -> \"" + automaton.getInitialState() + "\";");
buff.append(AUtil.lineSeparator);
for (Iterator i = automaton.getFinalStates().iterator(); i.hasNext(); ) {
IState s = (IState) i.next();
buff.append(" \"" + s + "\" [shape=doublecircle];");
buff.append(AUtil.lineSeparator);
}
List lines = new ArrayList();
for (Iterator i = automaton.getTransitions().iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
lines.add(" \"" + t.getPreState() + "\" -> \"" + t.getPostState() + "\" [label=\"" + labelGenerator.getLabel(t).replaceAll("\"", "\\\"") + "\"]" + ";");
}
Collections.sort(lines);
for (Iterator i = lines.iterator(); i.hasNext(); ) {
buff.append(i.next());
buff.append(AUtil.lineSeparator);
}
buff.append("}");
return buff.toString();
}
}

View File

@ -0,0 +1,42 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public class CharSymbol extends Symbol implements IValueSymbol {
public CharSymbol(String name) {
super(name);
char cs[] = name.toCharArray();
if (cs.length>1) {
throw(new AssertionError("a single character is expected."));
}
}
public CharSymbol(char c) {
this(Character.toString(c));
}
public CharSymbol(byte b) {
this(Character.toString((char)b));
}
public Object value() {
return new Character(charValue());
}
public byte byteValue() {
return (byte) getName().charAt(0);
}
public char charValue() {
return getName().charAt(0);
}
}

View File

@ -0,0 +1,51 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
import com.ibm.wala.automaton.AUtil;
public class ComplementTransition extends FilteredTransition {
static private class Condition implements ICondition {
private Collection transitions;
public Condition(Collection transitions) {
this.transitions = transitions;
}
public Condition(ITransition transitions[]) {
this(AUtil.list(transitions));
}
public boolean accept(ISymbol symbol, IMatchContext ctx) {
for (Iterator i = transitions.iterator(); i.hasNext(); ) {
ITransition t = (ITransition) i.next();
if (t.accept(symbol, ctx)) {
return false;
}
}
return true;
}
}
public ComplementTransition(IState preState, IState postState, IVariable inputSymbol, List outputSymbols, IFilter filter, Collection transitions) {
super(preState, postState, inputSymbol, outputSymbols, filter, new Condition(transitions));
}
public ComplementTransition(IState preState, IState postState, IVariable inputSymbol, ISymbol outputSymbols[], IFilter filter, ITransition transitions[]) {
super(preState, postState, inputSymbol, outputSymbols, filter, new Condition(transitions));
}
public ComplementTransition(IState preState, IState postState, IVariable inputSymbol, Iterator outputSymbols, IFilter filter, ITransition transitions[]) {
super(preState, postState, inputSymbol, AUtil.list(outputSymbols), filter, new Condition(transitions));
}
}

View File

@ -0,0 +1,74 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Collection;
public class DeepSTSCopier implements ISTSCopier {
private ITransitionCopier tCopier;
public DeepSTSCopier(ITransitionCopier tCopier) {
this.tCopier = tCopier;
}
public IStateTransitionSystem copy(IStateTransitionSystem sts) {
return (IStateTransitionSystem) sts.clone();
}
public ITransition copy(ITransition transition) {
return transition.copy(tCopier);
}
public Collection copyTransitions(Collection transitions) {
return tCopier.copyTransitions(transitions);
}
public IState copy(IState state) {
return state.copy(tCopier);
}
public Collection copyStates(Collection c) {
return tCopier.copyStates(c);
}
public String copyStateName(String name) {
return tCopier.copyStateName(name);
}
public IState copyStateReference(IState parent, IState state) {
return tCopier.copyStateReference(parent, state);
}
public Collection copyStateReferences(IState parent, Collection c) {
return tCopier.copyStateReferences(parent, c);
}
public ISymbol copy(ISymbol symbol) {
return symbol.copy(tCopier);
}
public Collection copySymbols(Collection symbols) {
return tCopier.copySymbols(symbols);
}
public String copyName(String name) {
return tCopier.copyName(name);
}
public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol) {
return tCopier.copySymbolReference(parent, symbol);
}
public Collection copySymbolReferences(ISymbol parent, Collection symbols) {
return tCopier.copySymbolReferences(parent, symbols);
}
}

View File

@ -0,0 +1,28 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public class DeepStateCopier extends AbstractStateCopier {
public IState copyStateReference(IState parent, IState state) {
if (state == null) {
return null;
}
else {
return state.copy(this);
}
}
public String copyStateName(String name) {
return name;
}
static final public DeepStateCopier defaultCopier = new DeepStateCopier();
}

View File

@ -0,0 +1,28 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public class DeepSymbolCopier extends AbstractSymbolCopier {
public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol) {
if (symbol == null) {
return null;
}
else {
return symbol.copy(this);
}
}
public String copyName(String name) {
return name;
}
static final public DeepSymbolCopier defaultCopier = new DeepSymbolCopier();
}

View File

@ -0,0 +1,72 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Collection;
public class DeepTransitionCopier extends AbstractTransitionCopier implements ITransitionCopier {
private ISymbolCopier symbolCopier;
private IStateCopier stateCopier;
public DeepTransitionCopier(ISymbolCopier symbolCopier, IStateCopier stateCopier) {
this.symbolCopier = symbolCopier;
this.stateCopier = stateCopier;
}
public DeepTransitionCopier() {
this(SimpleSymbolCopier.defaultCopier, SimpleStateCopier.defaultCopier);
}
public ITransition copy(ITransition transition) {
return (ITransition) transition.clone();
}
public IState copy(IState state) {
return state.copy(stateCopier);
}
public Collection copyStates(Collection c) {
return stateCopier.copyStates(c);
}
public String copyName(String name) {
return symbolCopier.copyName(name);
}
public String copyStateName(String name) {
return stateCopier.copyStateName(name);
}
public IState copyStateReference(IState parent, IState state) {
return stateCopier.copyStateReference(parent, state);
}
public Collection copyStateReferences(IState parent, Collection c) {
return stateCopier.copyStateReferences(parent, c);
}
public ISymbol copy(ISymbol symbol) {
return symbol.copy(symbolCopier);
}
public Collection copySymbols(Collection symbols) {
return symbolCopier.copySymbols(symbols);
}
public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol) {
return symbolCopier.copySymbolReference(parent, symbol);
}
public Collection copySymbolReferences(ISymbol parent, Collection c) {
return symbolCopier.copySymbolReferences(parent, c);
}
}

View File

@ -0,0 +1,138 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
public class FilteredTransition extends Transition {
public interface IFilter {
public List invoke(ISymbol symbol, List outputs);
}
public interface ICondition {
public boolean accept(ISymbol symbol, IMatchContext ctx);
}
static private IFilter DEFAULT_FILTER = new IFilter() {
public List invoke(ISymbol symbol, List outputs) {
return outputs;
}
};
static private ICondition DEFAULT_CONDITION = new ICondition(){
public boolean accept(ISymbol symbol, IMatchContext ctx) {
return true;
}
};
private IFilter filter;
private ICondition condition;
public FilteredTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols, IFilter filter, ICondition condition) {
super(preState, postState, inputSymbol, outputSymbols);
this.filter = (filter == null) ? DEFAULT_FILTER : filter;
this.condition = (condition == null) ? DEFAULT_CONDITION : condition;
}
public FilteredTransition(IState preState, IState postState, ISymbol inputSymbol, List outputSymbols, IFilter filter) {
super(preState, postState, inputSymbol, outputSymbols);
this.filter = (filter == null) ? DEFAULT_FILTER : filter;
this.condition = DEFAULT_CONDITION;
}
public FilteredTransition(IState preState, IState postState, ISymbol inputSymbol, ISymbol outputSymbols[], IFilter filter, ICondition condition) {
super(preState, postState, inputSymbol, outputSymbols);
this.filter = (filter == null) ? DEFAULT_FILTER : filter;
this.condition = (condition == null) ? DEFAULT_CONDITION : condition;
}
public FilteredTransition(IState preState, IState postState, ISymbol inputSymbol, ISymbol outputSymbols[], ICondition condition) {
super(preState, postState, inputSymbol, outputSymbols);
this.filter = DEFAULT_FILTER;
this.condition = (condition == null) ? DEFAULT_CONDITION : condition;
}
public FilteredTransition(IState preState, IState postState, ISymbol inputSymbol, ISymbol outputSymbols[], IFilter filter) {
super(preState, postState, inputSymbol, outputSymbols);
this.filter = (filter == null) ? DEFAULT_FILTER : filter;
this.condition = DEFAULT_CONDITION;
}
public FilteredTransition(IState preState, IState postState, ISymbol inputSymbol, ICondition condition) {
super(preState, postState, inputSymbol);
this.filter = DEFAULT_FILTER;
this.condition = (condition == null) ? DEFAULT_CONDITION : condition;
}
public void appendOutputSymbols(List outputs) {
super.appendOutputSymbols(outputs);
final int len = outputs.size();
final IFilter oldFilter = filter;
filter = new IFilter(){
public List invoke(ISymbol symbol, List outputs) {
List l = oldFilter.invoke(symbol, outputs.subList(0, outputs.size()-len));
l.addAll(outputs.subList(len-1, outputs.size()));
return l;
}
};
}
public void prependOutputSymbols(List outputs) {
super.prependOutputSymbols(outputs);
final int len = outputs.size();
final IFilter oldFilter = filter;
filter = new IFilter(){
public List invoke(ISymbol symbol, List outputs) {
List l = oldFilter.invoke(symbol, outputs.subList(len, outputs.size()));
l.addAll(0, outputs.subList(0, len));
return l;
}
};
}
public boolean accept(ISymbol s, IMatchContext ctx) {
return (!(s instanceof IVariable)) // don't accept variables.
&& super.accept(s, ctx)
&& condition.accept(s, ctx);
}
public List transit(ISymbol s) {
List outputs = super.transit(s);
if (outputs != null) {
return filter.invoke(s, outputs);
}
else {
return null;
}
}
public IFilter getFilter() {
return filter;
}
public ICondition getCondition() {
return condition;
}
public int hashCode() {
return super.hashCode() + filter.hashCode() + condition.hashCode();
}
public boolean equals(Object obj) {
if (super.equals(obj)) {
FilteredTransition t = (FilteredTransition) obj;
return filter.equals(t.filter) && condition.equals(t.condition);
}
else {
return false;
}
}
}

View File

@ -0,0 +1,25 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public class FlexibleNamingSymbol extends Symbol implements IFlexibleNamingSymbol {
public FlexibleNamingSymbol(String name) {
super(name);
}
public void setName(String name) {
super.setName(name);
}
public int hashCode() {
return System.identityHashCode(this);
}
}

View File

@ -0,0 +1,27 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Set;
import com.ibm.wala.automaton.AUtil;
public class FreshNameFactory {
private Set<String> names;
public FreshNameFactory(Set<String> usedVarNames) {
this.names = usedVarNames;
}
public String createName(String name) {
return AUtil.createUniqueName(name, names);
}
}

View File

@ -0,0 +1,26 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
public class FreshStateFactory extends FreshNameFactory implements IStateFactory {
IStateFactory baseFactory;
public FreshStateFactory(IStateFactory baseFactory, Set<String> stateNames) {
super(stateNames);
this.baseFactory = baseFactory;
}
public IState createState(String name) {
return baseFactory.createState(super.createName(name));
}
}

View File

@ -0,0 +1,26 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Set;
public class FreshSymbolFactory<T extends ISymbol> extends FreshNameFactory implements ISymbolFactory<T> {
private ISymbolFactory<T> baseFactory;
public FreshSymbolFactory(ISymbolFactory<T> factory, Set<String> names) {
super(names);
this.baseFactory = factory;
}
public T createSymbol(String name) {
return baseFactory.createSymbol(super.createName(name));
}
}

View File

@ -0,0 +1,34 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Set;
import com.ibm.wala.automaton.AUtil;
import com.ibm.wala.automaton.grammar.string.Grammars;
import com.ibm.wala.automaton.grammar.string.IGrammar;
public class FreshVariableFactory extends FreshSymbolFactory<IVariable> implements IVariableFactory<IVariable> {
public FreshVariableFactory(ISymbolFactory<IVariable> factory, Set<String> usedVarNames) {
super(factory, usedVarNames);
}
public FreshVariableFactory(ISymbolFactory<IVariable> factory, IGrammar g) {
this(factory, Grammars.collectVariableNames(Grammars.collectVariables(g)));
}
public IVariable createSymbol(String name) {
return super.createSymbol(name);
}
public IVariable createVariable(String name) {
return createSymbol(name);
}
}

View File

@ -0,0 +1,22 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
public interface IAutomaton extends IStateTransitionSystem {
Set getFinalStates();
// List<ISymbol> translate(List<ISymbol> symbols)
List translate(List symbols);
boolean accept(List symbols);
}

View File

@ -0,0 +1,14 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface IAutomatonVisitor extends ITransitionVisitor, IStateVisitor {
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface IFlexibleNamingSymbol {
public void setName(String name);
}

View File

@ -0,0 +1,20 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
public interface IMatchContext {
void put(ISymbol key, ISymbol val);
ISymbol get(ISymbol key);
Iterator iterator();
Map toMap();
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface ISTSCopier extends ITransitionCopier {
IStateTransitionSystem copy(IStateTransitionSystem sts);
}

View File

@ -0,0 +1,17 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface IState extends Cloneable {
String getName();
Object clone();
IState copy(IStateCopier copier);
}

View File

@ -0,0 +1,25 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Collection;
public interface IStateCopier {
IState copy(IState state);
Collection copyStates(Collection c);
String copyStateName(String name);
IState copyStateReference(IState parent, IState state);
Collection copyStateReferences(IState parent, Collection c);
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface IStateFactory {
IState createState(String name);
}

View File

@ -0,0 +1,31 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
public interface IStateTransitionSystem extends Cloneable {
IState getInitialState();
void setInitialState(IState state);
Set getTransitions();
Set getTransitions(IState preState);
Set getStates();
Set getTransitions(IState preState, ISymbol input);
Set getAcceptTransitions(IState preState, ISymbol input);
void traverseStates(IStateVisitor visitor);
void traverseTransitions(ITransitionVisitor visitor);
void traverse(IAutomatonVisitor visitor);
Object clone();
IStateTransitionSystem copy(ISTSCopier copier);
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface IStateVisitor {
void onVisit(IState state);
}

View File

@ -0,0 +1,31 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface ISymbol extends Cloneable {
String getName();
// this method is defined in IFlexibleNamingSymbol
//void setName(String name);
boolean matches(ISymbol symbol, IMatchContext context);
boolean possiblyMatches(ISymbol symbol, IMatchContext context);
void traverse(ISymbolVisitor visitor);
ISymbol copy(ISymbolCopier copier);
Object clone();
int size();
}

View File

@ -0,0 +1,21 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
public interface ISymbolCopier {
public ISymbol copy(ISymbol symbol);
public Collection copySymbols(Collection symbols);
public String copyName(String name);
public ISymbol copySymbolReference(ISymbol parent, ISymbol symbol);
public Collection copySymbolReferences(ISymbol parent, Collection symbols);
}

View File

@ -0,0 +1,15 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface ISymbolFactory<T extends ISymbol> {
T createSymbol(String name);
}

View File

@ -0,0 +1,16 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
public interface ISymbolVisitor {
void onVisit(ISymbol symbol);
void onLeave(ISymbol symbol);
}

View File

@ -0,0 +1,31 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.*;
public interface ITransition extends Cloneable {
public IState getPreState();
public IState getPostState();
public void setPreState(IState state);
public void setPostState(IState state);
public ISymbol getInputSymbol();
public void setInputSymbol(ISymbol s);
public Iterator getOutputSymbols();
public boolean hasOutputSymbols();
public void appendOutputSymbols(List outputs);
public void prependOutputSymbols(List outputs);
public boolean isEpsilonTransition();
public boolean accept(ISymbol symbol, IMatchContext ctx);
public List transit(ISymbol symbol);
public ITransition copy(ITransitionCopier copier);
public Object clone();
}

View File

@ -0,0 +1,18 @@
/******************************************************************************
* Copyright (c) 2002 - 2006 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*****************************************************************************/
package com.ibm.wala.automaton.string;
import java.util.Collection;
public interface ITransitionCopier extends IStateCopier, ISymbolCopier {
public ITransition copy(ITransition transition);
public Collection copyTransitions(Collection transitions);
}

Some files were not shown because too many files have changed in this diff Show More