/* * (C) Copyright 2005 Arnaud Bailly (arnaud.oqube@gmail.com), * Yves Roos (yroos@lifl.fr) and others. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package rationals.converters; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import rationals.Automaton; import rationals.NoSuchStateException; import rationals.State; import rationals.Transition; /** * A codec for rationals that stores an automaton in a specific format * similar to the {@see ToString} class output. * <strong>Note </strong> : the alphabet may not contains the * reserved characters '[', ',' , ']', '(', ')'. * * <pre> A = [ <comma separated alphabet> ]\n Q = [ <comma separated list of statess > ] \n I = [ <comma separated list of initials > ] \n T = [ <comma separated list of terminals > ] \n delta = [ \n ( to, label ,from ) \n ( to, label ,from ) \n .... \n ] \n * </pre> * @author nono * @version $Id: JAutoCodec.java 2 2006-08-24 14:41:48Z oqube $ * @see toAscii */ public class JAutoCodec implements StreamEncoder,StreamDecoder { /* (non-Javadoc) * @see rationals.converters.StreamEncoder#output(rationals.Automaton, java.io.OutputStream) */ public void output(Automaton a, OutputStream stream) throws IOException { PrintWriter pw = new PrintWriter(new OutputStreamWriter(stream)); pw.print(new toAscii().toString(a)); pw.flush(); } /* (non-Javadoc) * @see rationals.converters.StreamDecoder#input(java.io.InputStream) */ public Automaton input(InputStream is) throws IOException { BufferedReader rd = new BufferedReader(new InputStreamReader(is)); Automaton a = new Automaton(); Map /* < String, State > */ smap = new HashMap(); /* regexes for various parts */ Pattern set = Pattern.compile("\\[\\s*(.*)\\s*\\]"); Pattern trans = Pattern.compile("\\((.*)[ ]*,(.*),[ ]*([^)]*)\\)"); /* read the alphabet - and discard it */ String alph = rd.readLine(); /* read states */ String states = rd.readLine(); Matcher stm = set.matcher(states.substring(4)); if(!stm.find()) throw new IOException("Failed to parse states set in input stream "+states); String tmp = stm.group(0); states = stm.group(1); StringTokenizer st = new StringTokenizer(states,","); Set /* < String > */ sset = new HashSet(); /* set of all states */ while(st.hasMoreTokens()) { String s = st.nextToken().trim(); sset.add(s); } /* read initials */ states = rd.readLine(); stm = set.matcher(states.substring(4)); if(!stm.find()) throw new IOException("Failed to parse initial states set in input stream "+states); states = stm.group(1); st = new StringTokenizer(states,","); Set /* < String > */ iset = new HashSet(); /* set of all states */ while(st.hasMoreTokens()) { String s = st.nextToken().trim(); iset.add(s); } /* read terminals */ states = rd.readLine(); stm = set.matcher(states.substring(4)); if(!stm.find()) throw new IOException("Failed to parse terminals set in string "+states); states = stm.group(1); st = new StringTokenizer(states,","); Set /* < String > */ tset = new HashSet(); /* set of all states */ while(st.hasMoreTokens()) { String s = st.nextToken().trim(); tset.add(s); } /* create states */ Iterator it= sset.iterator(); while(it.hasNext()) { boolean init,fini; String s = (String)it.next(); if(iset.contains(s)) init = true; else init =false; if(tset.contains(s)) fini = true; else fini = false; smap.put(s,a.addState(init,fini)); } /* transitions */ rd.readLine(); String trs = null; while(!(trs = rd.readLine()).equals("]")) { stm = trans.matcher(trs); if(!stm.find()) throw new IOException("Failed to parse transition in "+trs); State from = (State)smap.get(stm.group(1).trim()); String lbl = stm.group(2).trim(); if("1".equals(lbl)) lbl = null; State to = (State)smap.get(stm.group(3).trim()); if(from == null || to==null ) throw new IOException("Failed to parse states in transition "+trs); try { a.addTransition(new Transition(from,lbl,to)); } catch (NoSuchStateException e) { e.printStackTrace(); } } return a; } }