User:EMBee/Scrap
this code is based on [1] and [2] it is available under the GPL. the author has expressed permission to publish his code here, but has not yet confirmed that using the GNU FDL is ok. once i receive this confirmation i will add the code to S-Expressions
LispParser.java: <lang Java>package jfkbits;
import java.util.AbstractCollection; import java.util.Enumeration; import java.util.Iterator; import java.util.Vector;
public class LispParser
{
LispTokenizer tokenizer;
public LispParser(LispTokenizer input) {
tokenizer=input;
}
public class ParseException extends Exception {
}
public interface Expr { // abstract parent for Atom and ExprList }
public class ExprList extends Vector implements Expr { public String toString() { String output = "("; for(Enumeration it=this.elements(); it.hasMoreElements(); ) { Expr expr = (Expr) it.nextElement(); output += expr.toString(); if (it.hasMoreElements()) output += " "; } output += ")"; return output; }
public ExprList(AbstractCollection exprs) { super(exprs); }
}
public class Atom implements Expr {
String name;
public String toString() { return name; } public Atom(String text) { name = text; }
}
public Expr parseExpr() throws ParseException { Token token = tokenizer.nextToken(); Expr retval = (token.type == '(')? parseExprList(token) : constructAtom(token); return retval; }
protected Expr parseExprList(Token openParen) throws ParseException
{
Vector acc = new Vector();
while(tokenizer.peekToken().type != ')')
{
Expr element = parseExpr();
acc.add(element);
}
Token closeParen = tokenizer.nextToken();
Expr retval = constructExprList(acc); return retval; }
protected Expr constructAtom(Token token) { return new Atom(token.text); }
protected Expr constructExprList( AbstractCollection exprs) { ExprList retval = new ExprList(exprs); return retval; }
} </lang>
LispTokenizer.java: <lang java> package jfkbits;
import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.io.StreamTokenizer; import java.io.StringReader; import java.util.Iterator;
public class LispTokenizer implements Iterator {
// Instance variables have default access to allow unit tests access. StreamTokenizer m_tokenizer; IOException m_ioexn;
/** Constructs a tokenizer that scans input from the given string. * @param src A string containing S-expressions. */ public LispTokenizer(String src) { this(new StringReader(src)); }
/** Constructs a tokenizer that scans input from the given Reader. * @param r Reader for the character input source */ public LispTokenizer(Reader r) { if(r == null) r = new StringReader(""); BufferedReader buffrdr = new BufferedReader(r); m_tokenizer = new StreamTokenizer(buffrdr); m_tokenizer.resetSyntax(); // We don't like the default settings
m_tokenizer.whitespaceChars(0, ' '); m_tokenizer.wordChars(' '+1,255); m_tokenizer.ordinaryChar('('); m_tokenizer.ordinaryChar(')'); m_tokenizer.ordinaryChar('\); m_tokenizer.commentChar(';'); m_tokenizer.quoteChar('"'); }
public Token peekToken() { if(m_ioexn != null) return null; try { m_tokenizer.nextToken(); } catch(IOException e) { m_ioexn = e; return null; } if(m_tokenizer.ttype == StreamTokenizer.TT_EOF) return null; Token token = new Token(m_tokenizer); m_tokenizer.pushBack(); return token; } public boolean hasNext() { if(m_ioexn != null) return false; try { m_tokenizer.nextToken(); } catch(IOException e) { m_ioexn = e; return false; } if(m_tokenizer.ttype == StreamTokenizer.TT_EOF) return false; m_tokenizer.pushBack(); return true; }
/** Return the most recently caught IOException, if any, * * @return */ public IOException getIOException() { return m_ioexn; }
public Token nextToken() { return (Token)next(); }
public Object next() { try { m_tokenizer.nextToken(); } catch(IOException e) { m_ioexn = e; return null; }
Token token = new Token(m_tokenizer); return token; }
public void remove() { }
} </lang>
SexprDemo.java: <lang Java> import java.io.IOException; import java.util.AbstractCollection;
import jfkbits.LispParser; import jfkbits.LispParser.Expr; import jfkbits.LispParser.ExprList; import jfkbits.LispParser.ParseException; import jfkbits.LispTokenizer; import jfkbits.Token;
public class SexprDemo { public static void main(String args[]) throws IOException {
LispTokenizer tzr = new LispTokenizer("((data \"quoted data\" 123 4.5) (data (!@# (4.5) \"(more\" \"data)\")))"); LispParser parser = new LispParser(tzr); ExprList result = null; Enumeration output = null; try
{ result = (ExprList) parser.parseExpr(); System.out.println(result.toString()); } catch (ParseException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }
} } </lang>