User:EMBee/Scrap: Difference between revisions

From Rosetta Code
Content added Content deleted
(simplify code)
m (content moved to S-Expressions)
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>

Revision as of 13:41, 27 October 2011