package fr.orsay.lri.varna.controlers; import java.awt.Color; import java.io.StreamTokenizer; import java.io.StringReader; import java.util.ArrayList; import java.util.Hashtable; import java.util.Vector; import javax.swing.JOptionPane; import fr.orsay.lri.varna.VARNAPanel; import fr.orsay.lri.varna.models.annotations.ChemProbAnnotation; import fr.orsay.lri.varna.models.annotations.ChemProbAnnotation.ChemProbAnnotationType; import fr.orsay.lri.varna.models.rna.ModeleColorMap; import fr.orsay.lri.varna.models.rna.RNA; public class ControleurScriptParser { private static String SCRIPT_ERROR_PREFIX = "Error"; private static class Command{ Function _f; Vector _argv; public Command(Function f, Vector argv) { _f = f; _argv = argv; } }; private static abstract class Argument{ ArgumentType _t; public Argument(ArgumentType t) { _t = t; } public ArgumentType getType() { return _t; } public abstract String toString(); }; private static class NumberArgument extends Argument{ Number _val; public NumberArgument(Number val) { super(ArgumentType.NUMBER_TYPE); _val = val; } public Number getNumber() { return _val; } public String toString() { return _val.toString(); } }; private static class ColorArgument extends Argument{ Color _val; public ColorArgument(Color val) { super(ArgumentType.COLOR_TYPE); _val = val; } public Color getColor() { return _val; } public String toString() { return _val.toString(); } }; private static class BooleanArgument extends Argument{ boolean _val; public BooleanArgument(boolean val) { super(ArgumentType.BOOLEAN_TYPE); _val = val; } public boolean getBoolean() { return _val; } public String toString() { return ""+_val; } }; private static class StringArgument extends Argument{ String _val; public StringArgument(String val) { super(ArgumentType.STRING_TYPE); _val = val; } public String toString() { return _val.toString(); } }; private static class ArrayArgument extends Argument{ Vector _val; public ArrayArgument(Vector val) { super(ArgumentType.ARRAY_TYPE); _val = val; } public int getSize() { return _val.size(); } public Argument getArgument(int i) { return _val.get(i); } public String toString() { return _val.toString(); } }; private enum ArgumentType{ STRING_TYPE, NUMBER_TYPE, BOOLEAN_TYPE, ARRAY_TYPE, COLOR_TYPE }; private enum Function{ ADD_CHEM_PROB("addchemprob",new ArgumentType[] {ArgumentType.NUMBER_TYPE,ArgumentType.NUMBER_TYPE,ArgumentType.STRING_TYPE,ArgumentType.NUMBER_TYPE,ArgumentType.COLOR_TYPE,ArgumentType.BOOLEAN_TYPE}), ERASE_SEQ("eraseseq",new ArgumentType[] {}), RESET_CHEM_PROB("resetchemprob",new ArgumentType[] {}), SET_COLOR_MAP_MIN("setcolormapminvalue",new ArgumentType[]{ArgumentType.NUMBER_TYPE}), SET_COLOR_MAP_MAX("setcolormapmaxvalue",new ArgumentType[]{ArgumentType.NUMBER_TYPE}), SET_COLOR_MAP("setcolormap",new ArgumentType[]{ArgumentType.STRING_TYPE}), SET_CUSTOM_COLOR_MAP("setcustomcolormap",new ArgumentType[]{ArgumentType.ARRAY_TYPE}), SET_SEQ("setseq",new ArgumentType[]{ArgumentType.STRING_TYPE}), SET_STRUCT("setstruct",new ArgumentType[]{ArgumentType.STRING_TYPE}), SET_STRUCT_SMOOTH("setstructsmooth",new ArgumentType[] {ArgumentType.STRING_TYPE}), SET_TITLE("settitle",new ArgumentType[] {ArgumentType.STRING_TYPE}), SET_RNA("setrna",new ArgumentType[]{ArgumentType.STRING_TYPE,ArgumentType.STRING_TYPE}), SET_RNA_SMOOTH("setrnasmooth",new ArgumentType[]{ArgumentType.STRING_TYPE,ArgumentType.STRING_TYPE}), SET_SELECTION("setselection",new ArgumentType[]{ArgumentType.ARRAY_TYPE}), SET_VALUES("setvalues",new ArgumentType[]{ArgumentType.ARRAY_TYPE}), TOGGLE_SHOW_COLOR_MAP("toggleshowcolormap",new ArgumentType[]{}), REDRAW("redraw",new ArgumentType[] {ArgumentType.STRING_TYPE}), UNKNOWN("N/A",new ArgumentType[] {}); String _funName; ArgumentType[] _args; Function(String funName, ArgumentType[] args) { _funName = funName; _args = args; } ArgumentType[] getPrototype() { return this._args; } String getFunName() { return this._funName; } }; private static Hashtable _name2Fun = new Hashtable(); private static Hashtable _fun2Prot = new Hashtable(); private static void initFunctions() { if (_name2Fun.size()>0) { return; } Function[] funs = Function.values(); for(int i=0;i cmds = parseScript(cmdtxt); for(int i=0;i vals = new ArrayList(); for (int j=0;j parseArguments(StreamTokenizer st, boolean parType) throws Exception { Vector result = new Vector(); while((st.ttype!=')' && parType) || (st.ttype!=']' && !parType)) { st.nextToken(); //System.out.println(""+ (parType?"Par.":"Bra.")+" "+(char)st.ttype); switch(st.ttype) { case(StreamTokenizer.TT_NUMBER): { result.add(new NumberArgument(st.nval)); } break; case(StreamTokenizer.TT_WORD): { Color c = parseColor(st.sval); if (c!=null) { result.add(new ColorArgument(c)); } else { Boolean b = parseBoolean(st.sval); if (b!=null) { result.add(new BooleanArgument(b)); } else { result.add(new StringArgument(st.sval)); } } } break; case('"'): { result.add(new StringArgument(st.sval)); } break; case('['): { result.add(new ArrayArgument(parseArguments(st, false))); } break; case('('): { result.add(new ArrayArgument(parseArguments(st, true))); } break; case(')'): { if (parType) return result; else throw new Exception(SCRIPT_ERROR_PREFIX+": Opening "+(parType?"parenthesis":"bracket")+" matched with a closing "+(!parType?"parenthesis":"bracket")); } case(']'): { if (!parType) return result; else throw new Exception(SCRIPT_ERROR_PREFIX+": Opening "+(parType?"parenthesis":"bracket")+" matched with a closing "+(!parType?"parenthesis":"bracket")); } case(','): break; case(StreamTokenizer.TT_EOF): { throw new Exception(SCRIPT_ERROR_PREFIX+": Unmatched opening "+(parType?"parenthesis":"bracket")); } } } return result; } private static Command parseCommand(String cmd) throws Exception { int cut = cmd.indexOf("("); if (cut==-1) { throw new Exception(SCRIPT_ERROR_PREFIX+": Syntax error"); } String fun = cmd.substring(0,cut); Function f = getFunction(fun); if (f==Function.UNKNOWN) { throw new Exception(SCRIPT_ERROR_PREFIX+": Unknown function \""+fun+"\""); } StreamTokenizer st = new StreamTokenizer(new StringReader(cmd.substring(cut+1))); st.eolIsSignificant(false); st.parseNumbers(); st.quoteChar('\"'); st.ordinaryChar('='); st.ordinaryChar(','); st.ordinaryChar('['); st.ordinaryChar(']'); st.ordinaryChar('('); st.ordinaryChar(')'); st.wordChars('#', '#'); Vector argv = parseArguments(st,true); checkArgs(f,argv); Command result = new Command(f,argv); return result; } private static boolean checkArgs(Function f, Vector argv) throws Exception { ArgumentType[] argtypes = getPrototype(f); if (argtypes.length!=argv.size()) throw new Exception(SCRIPT_ERROR_PREFIX+": Wrong number of argument for function \""+f+"\"."); for (int i=0;i parseScript(String cmd) throws Exception { initFunctions(); Vector cmds = new Vector(); String[] data = cmd.split(";"); for (int i=0;i