User:EMBee/Scrap: Difference between revisions

From Rosetta Code
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>

Revision as of 13:41, 27 October 2011