package ca.umontreal.iro.rali; import java.io.Reader; import java.io.IOException; import java.io.StreamTokenizer; import java.io.StringReader; // /** * Specialized StreamTokeniser to simplify parsing of an XPath expression * to be split in parts */ public class XPathTokenizer { private StreamTokenizer st; /** * Set up the tokenizer over a Reader * the only "interesting" tokens are [ ] / ' and " * @param r reader to specialize */ XPathTokenizer(Reader r){ st = new StreamTokenizer(r); st.resetSyntax(); // remove parsing of numbers... st.wordChars('\u0000','\uFFFF'); // everything is part of a word // except the following... st.ordinaryChar('['); st.ordinaryChar(']'); st.ordinaryChar('/'); st.quoteChar('\''); st.quoteChar('"'); } /** * Create a tokenizer over a String * @param str the String to tokenize as an XPath */ XPathTokenizer(String str){ this(new StringReader(str)); } /** * Check if there are any token left * @return true if there any token to be read */ public boolean hasNext(){ return st.ttype!=StreamTokenizer.TT_EOF; } /** * Check if current token is a string * @return true if the current token is a string */ public boolean isString(){ return st.ttype=='\''||st.ttype=='"'; } /** * Get a new token and return it as a String * @return the string version of the new token * @throws IOException */ public String nextToken() throws IOException{ st.nextToken(); // System.out.println(":"+getToken()+":"); return getToken(); } /** * Return the current token * @return string version of the current token */ public String getToken(){ return (st.ttype == StreamTokenizer.TT_WORD || isString()) ? st.sval : (""+(char)st.ttype); } /** * Check if the current token is @sym and return the next one * if this is not the case then raise an exception * * @param sym the token to check with * @return the value of the next token * @throws IOException */ public String skip(String sym) throws IOException { if(getToken().equals(sym)) return nextToken(); else throw new IllegalArgumentException("skip: '"+sym+"' expected but '"+ getToken() +"' found "); } /** * Some unit testing of this class * @param args */ public static void main(String[] args){ String test="/dubois/verbe/mot[@no='01']/text()[.=\"adoucir\"]"; XPathTokenizer pt=new XPathTokenizer(test); try { pt.nextToken(); while(pt.hasNext()){ System.out.println(pt.getToken()+(pt.isString()?"*":"")); pt.nextToken(); } } catch (IOException e) { System.out.println("eof..."); } } }