package nl.bluering; import java.io.*; import java.util.*; /** * A CoolFileHandle can be used to read files. It is cool * because it can tokenize the file: with get you can ask * for a token that matches the given regular expression. This makes * it ideal for building parsers with. * Another cool feature is that you can rewind the file to a previous * position (also very handy for parsing). */ public class CoolFileHandle { LineNumberReader f; char last=' '; boolean EOF=false; /** * creates a CFH for parsing the given string. Good for testing. * @param text the string to parse * @throws Exception in case something went wrong with the file. */ public CoolFileHandle(String text) throws Exception {f=new LineNumberReader(new PushbackReader(new StringReader(text))); read(); } /** * parses the given file. * @param ff the file to open * @throws Exception in case something went wrong with the file. */ public CoolFileHandle(File ff) throws Exception { try { f=new LineNumberReader(new PushbackReader(new FileReader(ff))); }catch(Exception e) {die("IOException when opening file "+ff); } read(); } StringBuffer pbbuf; int pos; /** * closes the CFH. You need to do this when you are finished. * If an exception was thrown, the CFH is already closed. But it doesn't * hurt to close a CFH twice. */ public void close() {try {f.close();}catch(Exception e){} } public boolean EOF() {return EOF&&(pbbuf==null||pos==pbbuf.length()); } void read() throws Exception { if (pbbuf!=null) { if(pos *
in(abc)
matches one character if it is a,b or c
*
out(abc)
matches one character that is not in abc
*
ignore(sub1)
tries to get sub1 from the stream, but does not return it
*
insert(abc)
returns abc without doing anything with the file * .You can say it is the opposite of ignore.
*
not(sub1)
returns the empty string if it can't get sub1
*
or(sub1,sub2)
first tries to get sub1, then tries sub2
*
quote(abc)
tries to get "abc" from the string
*
and(sub1,sub2)
tries to get sub1 followed by sub2 from the stream
*
few(sub1)
tries to get any number of sub1 from the stream. It is lazy, * so it will try to get as few as possible first. Note that few is more efficient * than many
*
many(sub1)
tries to get any number of sub1 from the stream. It is greedy, * so it tries to get as much sub1 as possible. Note that this is just a search order * difference, because it will backtrack if the next element fails.
*
allin(abc)
This parses all characters that appear in abc. It does not * do backtracking like many or few. It is thus very efficient.
*
allout(abc)
The opposite of allin: it gets all characters outside abc
*
maybe(sub1)
parses sub1 if available, otherwise just return the empty string.
*
dontcare(sub1)
This is equal to ignore(maybe(sub1))
* * @throws Exception if a technical error with the current file happened * */ public String get(Expression pattern) throws Exception { String r; if (!buffering) {buffer(true); r=get(pattern,null); buffer(false); } else r=get(pattern,null); return r; } static int MAX=100; String get(Expression pattern, Expression rest) throws Exception { if(pattern==null) return ""; String r="",s=null; int pos1=getpos(); if(pattern.isfunction("in")) {if(!EOF()&&pattern.get(0).toString().indexOf(last)!=-1) { return dotherest(""+lastread(),rest,pos1); } return restore(pos1); } else if(pattern.isfunction("allin")) { StringBuffer sb=new StringBuffer(); String arg=pattern.get(0).toString(); while(!EOF()&&arg.indexOf(last)!=-1) { sb.append((char)lastread()); } s=get(rest,null); if(s!=null) return sb.toString()+s; setpos(pos1); return null; } else if(pattern.isfunction("out")) {if(!EOF()&&pattern.get(0).toString().indexOf(last)==-1) { char l=lastread(); s=get(rest,null); if(s!=null) return l+s; setpos(pos1); } return null; } else if(pattern.isfunction("allout")) { StringBuffer sb=new StringBuffer(); String arg=pattern.get(0).toString(); while(!EOF()&&arg.indexOf(last)==-1) { sb.append((char)lastread()); } s=get(rest,null); if(s!=null) return sb.toString()+s; setpos(pos1); return null; } else if(pattern.isfunction("ignore",1)) { if(get(pattern.get(0),null)==null) return restore(pos1); return get(rest,null); } else if(pattern.isfunction("insert",1)) { return pattern.get(0).toString()+get(rest,null); } else if(pattern.isfunction("replace")) { if(get(pattern.get(0),null)!=null) return dotherest(pattern.get(1).toString(),rest,pos1); return restore(pos1); } else if(pattern.isfunction("not")) { if(get(pattern.get(0),null)==null) return get(rest,null); else return restore(pos1); } else if (pattern.isfunction("dontcare")) { get(pattern.get(0),null); return dotherest("",rest,pos1); } else if (pattern.isfunction("maybe")) { r=get(pattern.get(0),null); if(r==null) r=""; return dotherest(r,rest,pos1); } else if (pattern.isfunction("or")) {for(int i=0;i=0;count--) { c=get(rest,null); if (c!=null) { r=""; for(int i=0;i"+cfh1.get(e4)); }catch(Exception e) {e.printStackTrace(); } } }