User:EMBee/Scrap: Difference between revisions
Content added Content deleted
(simplify code) |
m (content moved to S-Expressions) |
||
Line 1: | Line 1: | ||
this code is based on [http://jfkbits.blogspot.com/2008/05/thoughts-on-s-expression-parser.html] and [http://jfkbits.blogspot.com/2008/05/thoughts-on-s-expression-lexer.html] |
|||
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]] |
|||
: You should give the name of the original author. Giving a URL is not enough while the content at the given URL may disappear. |
|||
LispParser.java: |
|||
<lang Java>package jfkbits; |
|||
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 ExprList() |
|||
{ |
|||
super(); |
|||
} |
|||
} |
|||
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) |
|||
: new Atom(token.text); |
|||
return retval; |
|||
} |
|||
protected Expr parseExprList(Token openParen) throws ParseException |
|||
{ |
|||
ExprList acc = new ExprList(); |
|||
while(tokenizer.peekToken().type != ')') |
|||
{ |
|||
Expr element = parseExpr(); |
|||
acc.add(element); |
|||
} |
|||
Token closeParen = tokenizer.nextToken(); |
|||
return acc; |
|||
} |
|||
} |
|||
</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> |
|||
{{Lines_too_long|Java}} |
|||
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> |