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:
parent
36bd8e5b23
commit
978000eff4
|
@ -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>
|
|
@ -0,0 +1,6 @@
|
|||
#*
|
||||
*#
|
||||
*~
|
||||
*.class
|
||||
bin
|
||||
build
|
|
@ -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:<?xml version="1.0" encoding="UTF-8"?> <launchConfigurationWorkingSet editPageId="org.eclipse.ui.resourceWorkingSetPage" factoryID="org.eclipse.ui.internal.WorkingSetFactory" label="workingSet" name="workingSet"> <item factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/com.ibm.capa.util.automaton/src/com/ibm/capa/util/automaton/parser/AmtParser.jy" type="1"/> </launchConfigurationWorkingSet>}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v "${resource_loc}""/>
|
||||
<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>
|
|
@ -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><project>/.externalToolBuilders/KMYacc.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -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
|
|
@ -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.
|
|
@ -0,0 +1,4 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -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>
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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."));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
y.output
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 ? "*" : "+");
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -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."));
|
||||
}
|
||||
|
||||
}
|
|
@ -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."));
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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 + "}}";
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue