From: Jamie Border
Subject: [OT] S-expression parser in C#?
Date: 
Message-ID: <dbj1eb$6ev$1@nwrdmz03.dmz.ncs.ea.ibs-infra.bt.com>
Tangentially CL-related, I guess:

Anybody know of a good(ish) example of this?

I've just hand-rolled a reasonable (but slowish) s-exp parser in C#, but I'm 
not happy with the result (slow).

Jamie 

From: Pietro Campesato
Subject: Re: S-expression parser in C#?
Date: 
Message-ID: <1121790512.774228.36330@g14g2000cwa.googlegroups.com>
I would be interested in that too.
From: Pascal Costanza
Subject: Re: S-expression parser in C#?
Date: 
Message-ID: <3k4rvvFs9htbU1@individual.net>
Pietro Campesato wrote:
> I would be interested in that too.

I don't know anything in that direction, but I recall reading threads 
here in c.l.l that have discussed s-expression libraries for Java. Maybe 
that's a starting point.

Another good bet is to check out the various Lisp and Scheme 
implementations for .NET. They _have_ to read in s-expressions. The 
question is whether they have cleanly separated this in reusable libraries.

I hope this helps.


Pascal

-- 
2nd European Lisp and Scheme Workshop
July 26 - Glasgow, Scotland - co-located with ECOOP 2005
http://lisp-ecoop05.bknr.net/
From: Geoffrey Summerhayes
Subject: Re: S-expression parser in C#?
Date: 
Message-ID: <2LbDe.2601$Qi4.377038@news20.bellglobal.com>
"Pascal Costanza" <··@p-cos.net> wrote in message 
···················@individual.net...
> Pietro Campesato wrote:
>> I would be interested in that too.
>
> I don't know anything in that direction, but I recall reading threads here 
> in c.l.l that have discussed s-expression libraries for Java. Maybe that's 
> a starting point.
>
> Another good bet is to check out the various Lisp and Scheme 
> implementations for .NET. They _have_ to read in s-expressions. The 
> question is whether they have cleanly separated this in reusable 
> libraries.
>

I wonder how amenable ABCL would be to a C# port?

--
Geoff 
From: Pascal Costanza
Subject: Re: S-expression parser in C#?
Date: 
Message-ID: <3k51d7FssltmU1@individual.net>
Geoffrey Summerhayes wrote:
> "Pascal Costanza" <··@p-cos.net> wrote in message 
> ···················@individual.net...
> 
>>Pietro Campesato wrote:
>>
>>>I would be interested in that too.
>>
>>I don't know anything in that direction, but I recall reading threads here 
>>in c.l.l that have discussed s-expression libraries for Java. Maybe that's 
>>a starting point.
>>
>>Another good bet is to check out the various Lisp and Scheme 
>>implementations for .NET. They _have_ to read in s-expressions. The 
>>question is whether they have cleanly separated this in reusable 
>>libraries.
> 
> I wonder how amenable ABCL would be to a C# port?

It's probably easier to port it to J# (or whatever Microsoft's version 
of Java is currently called). Then you could use it as a library from 
C#. (The .NET language interop thing should be good for something, right? ;)


Pascal

-- 
2nd European Lisp and Scheme Workshop
July 26 - Glasgow, Scotland - co-located with ECOOP 2005
http://lisp-ecoop05.bknr.net/
From: Kevin Smith
Subject: Re: S-expression parser in C#?
Date: 
Message-ID: <3QeDe.22070$3j2.572159@twister.southeast.rr.com>
Pascal Costanza wrote:
> Geoffrey Summerhayes wrote:
> 
>> "Pascal Costanza" <··@p-cos.net> wrote in message 
>> ···················@individual.net...
>>
>>> Pietro Campesato wrote:
>>>
>>>> I would be interested in that too.
>>>
>>>
>>> I don't know anything in that direction, but I recall reading threads 
>>> here in c.l.l that have discussed s-expression libraries for Java. 
>>> Maybe that's a starting point.
>>>
>>> Another good bet is to check out the various Lisp and Scheme 
>>> implementations for .NET. They _have_ to read in s-expressions. The 
>>> question is whether they have cleanly separated this in reusable 
>>> libraries.
>>
>>
>> I wonder how amenable ABCL would be to a C# port?
> 
> 
> It's probably easier to port it to J# (or whatever Microsoft's version 
> of Java is currently called). Then you could use it as a library from 
> C#. (The .NET language interop thing should be good for something, 
> right? ;)
> 
> 
> Pascal
> 
You might also be able to leverage IKVM (http://www.ikvm.net/) and ABCL. 
  IKVM emulates the JVM and allows Java code to run unaltered 
(supposedly) on the .NET CLR. I've read reports which claim that IKVM is 
complete enough to run Tomcat and Eclipse.

--Kevin
From: pp
Subject: Re: S-expression parser in C#?
Date: 
Message-ID: <1121861410.430564.117950@g14g2000cwa.googlegroups.com>
try:

http://sourceforge.net/projects/luna-scheme/

It's Scheme not CL but might not be too hard to tweak the parser.

-pp
From: Joe Marshall
Subject: Re: [OT] S-expression parser in C#?
Date: 
Message-ID: <8y01l1w9.fsf@ccs.neu.edu>
"Jamie Border" <·····@jborder.com> writes:

> Tangentially CL-related, I guess:
>
> Anybody know of a good(ish) example of this?
>
> I've just hand-rolled a reasonable (but slowish) s-exp parser in C#, but I'm 
> not happy with the result (slow).
>
> Jamie 

Here is a trivial one I wrote for playing around.  I never benchmarked
it, so it may be dog slow.  In addition to reading SExps, it tracks
the line and column.  It also returns tokens that represent whitespace
and comments (I wanted to transform Lisp files but retain the
formatting and comments).

I have omitted the definitions of the `Form' class and its subclasses,
but that should be pretty obvious.

If this is of interest at all, I'll put it on the web.

~jrm

-------

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;


namespace hack
{
    public class Reader
    {
        TextReader inputStream;
        FilePosition FilePos;
        int PeekCount;
        int ListDepth;

        public Reader (TextReader inputStream)
        {
            this.inputStream = inputStream;
            this.FilePos =  new FilePosition (0, 0, 0);
            // PeekCount = 0;
            // ListDepth = 0;
        }

        public void CheckPeekCount ()
        {
            this.PeekCount += 1;
            if (this.PeekCount > 1000000)
                throw new ReaderException ();
        }

        public bool AtEndOfFile ()
        {
            CheckPeekCount ();
            return this.inputStream.Peek () == -1;
        }

        public char PeekChar ()
        {
            CheckPeekCount ();
            return (char)(this.inputStream.Peek ());
        }

        public char ReadChar ()
        {
            CheckPeekCount ();
            char result = (char)(this.inputStream.Read ());
            this.FilePos = this.FilePos.Advance (result);
            return result;
        }

        public void DiscardChar ()
        {
            ReadChar ();
            return;
        }

        public Form ReadComment (FilePosition commentStart)
        {
            List<char> commentText = new List<char> ();
            while (true) {
                if (AtEndOfFile()) {
                    return new CommentForm (commentStart, new String (commentText.ToArray ()));
                }
                char peeked = PeekChar ();
                if (peeked == '\n') {
                    commentText.Add (ReadChar ());
                    return new CommentForm (commentStart, new String (commentText.ToArray ()));
                }
                commentText.Add (ReadChar ());
            }
        }

        Form ReadDot ()
        {
            FilePosition dotStart = this.FilePos;
            this.DiscardChar ();
            if (this.AtEndOfFile ()) return new DotForm (dotStart);
            char peeked = this.PeekChar ();
            if (Char.IsWhiteSpace (peeked))
                return new DotForm (dotStart);
            else if (peeked == '.')
                return ReadDotDot (dotStart);
            else
                return ReadSymbol (dotStart);
        }

        Form ReadDotDot (FilePosition dotStart)
        {
            this.DiscardChar ();
            if (this.AtEndOfFile ())
                throw new ReaderException ();
            char peeked = this.PeekChar ();
            if (peeked == '.')
                return ReadDotDotDot (dotStart);
            else
                throw new ReaderException ();
        }

        Form ReadDotDotDot (FilePosition dotStart)
        {
            this.DiscardChar ();
            if (this.AtEndOfFile ())
                return new EllipsesForm (dotStart);
            char peeked = this.PeekChar ();
            if (IsSymbolConstituent (peeked))
                throw new ReaderException ();
            else
                return new EllipsesForm (dotStart);
        }

        Form ReadList (FilePosition listStart)
        {
            bool improper = false;
            List<Form> subelements = new List<Form>();
            this.ListDepth += 1;
            this.DiscardChar ();

            while (true) {
                if (this.AtEndOfFile ())
                    throw new ReaderException ();

                char peeked = this.PeekChar ();

                if (peeked == ')') {
                    // Console.WriteLine ("Finishing list.");
                    this.DiscardChar ();
                    this.ListDepth -= 1;
                    return improper
                        ? (ListForm) (new ImproperListForm (listStart, subelements.ToArray()))
                        : (ListForm) (new ProperListForm (listStart, subelements.ToArray ()));
                }
                else if (peeked == '.') {
                    Form element = this.ReadDot ();
                    if (element is DotForm) {
                        if (improper)
                            throw new ReaderException ();
                        else
                            improper = true;
                    }
                    subelements.Add (element);
                }
                else {

                    Form element = this.Read ();
                    // Console.WriteLine ("Adding element {0} to list.", element);
                    subelements.Add (element);
                }
            }
        }

        Form ReadVector (FilePosition listStart)
        {
            List<Form> subelements = new List<Form> ();
            this.ListDepth += 1;
            this.DiscardChar ();

            while (true) {
                if (this.AtEndOfFile ())
                    throw new ReaderException ();

                char peeked = this.PeekChar ();

                if (peeked == ')') {
                    // Console.WriteLine ("Finishing list.");
                    this.DiscardChar ();
                    this.ListDepth -= 1;
                    return new VectorForm (listStart, subelements.ToArray ());
                }
                else if (peeked == '.') {
                    Form element = this.ReadDot ();
                    if (element is DotForm) 
                            throw new ReaderException ();
            
                    subelements.Add (element);
                }
                else {

                    Form element = this.Read ();
                    // Console.WriteLine ("Adding element {0} to list.", element);
                    subelements.Add (element);
                }
            }
        }

        public static bool IsSymbolConstituent (char c)
        {
            return Char.IsLetterOrDigit (c)
                   || c == '-'
                   || c == '_'
                   || c == '/'
                   || c == '?'
                   || c == '*'
                   || c == '!'
                   || c == '='
                   || c == '>';
        }

        public static bool IsSymbolInitial (char c)
        {
            return IsSymbolConstituent (c);
        }

        public Form ReadSymbol (FilePosition symbolStart)
        {
            List<char> characters = new List<char> ();
            while (true) {
                if (this.AtEndOfFile ())
                    return new SymbolForm (symbolStart, new string (characters.ToArray ()));
                char peeked = this.PeekChar ();

                if (IsSymbolConstituent (peeked))
                    characters.Add (this.ReadChar());
                else
                    return new SymbolForm (symbolStart, new string (characters.ToArray()));
            }
        }

        Form ReadWhitespace (FilePosition whitespaceStart)
        {
            List<char> characters = new List<char> ();
            while (true) {
                if (this.AtEndOfFile ())
                    return new WhitespaceForm (whitespaceStart, new string (characters.ToArray ()));
                char peeked = this.PeekChar ();
                if (Char.IsWhiteSpace (peeked))
                    characters.Add (this.ReadChar ());
                else
                    return new WhitespaceForm (whitespaceStart, new string (characters.ToArray ()));
            }
        }

        Form ReadBoolean (FilePosition sharpStart)
        {
            char b = this.ReadChar ();
            if (this.AtEndOfFile ())
                return new BooleanForm (sharpStart, b);
            char peeked = this.PeekChar ();
            if (IsSymbolConstituent (peeked))
                throw new ReaderException ();
            else
                return new BooleanForm (sharpStart, b);
        }

        Form ReadSharp (FilePosition sharpStart)
        {
            this.DiscardChar ();
            if (this.AtEndOfFile ())
                throw new ReaderException ();
            char peeked = this.PeekChar ();
            if (peeked == 't' || peeked == 'T' || peeked == 'f' || peeked == 'F')
                return ReadBoolean (sharpStart);
            else if (peeked == '(')
                return ReadVector (sharpStart);
            else
                throw new ReaderException ();
        }

        Form ReadSingleQuote (FilePosition quoteStart)
        {
            List<Form> quoted = new List<Form>();
            this.DiscardChar();
            while (true) {
                if (this.AtEndOfFile())
                    throw new ReaderException();
                Form quoteTarget = this.Read();
                if (quoteTarget.CanFollowQuote)
                    quoted.Add (quoteTarget);
                else
                    throw new ReaderException ();

                if (! quoteTarget.IsNoise)
                    return new QuoteForm (quoteStart, quoted.ToArray());
            }
        }
        
        Form ReadBackQuote (FilePosition quoteStart)
        {
            List<Form> quoted = new List<Form>();
            this.DiscardChar();
            while (true) {
                if (this.AtEndOfFile())
                    throw new ReaderException();
                Form quoteTarget = this.Read();
                if (quoteTarget.CanFollowQuote)
                    quoted.Add (quoteTarget);
                else
                    throw new ReaderException ();

                if (! quoteTarget.IsNoise)
                    return new QuasiQuoteForm (quoteStart, quoted.ToArray());
            }
        }

        Form ReadCommaAt (FilePosition commaStart)
        {
            List<Form> quoted = new List<Form> ();
            this.DiscardChar ();
            while (true) {
                if (this.AtEndOfFile ())
                    throw new ReaderException ();
                Form quoteTarget = this.Read ();
                if (quoteTarget.CanFollowQuote)
                    quoted.Add (quoteTarget);
                else
                    throw new ReaderException ();

                if (! quoteTarget.IsNoise)
                    return new UnquoteSplicingForm (commaStart, quoted.ToArray ());
            }
        }

        Form ReadComma (FilePosition commaStart)
        {
            this.DiscardChar ();
            if (this.AtEndOfFile ())
                throw new ReaderException ();
            char peeked = this.PeekChar ();
            if (peeked == ·@')
                return ReadCommaAt (commaStart);
            else {
                List<Form> quoted = new List<Form> ();
                while (true) {
                    if (this.AtEndOfFile ())
                        throw new ReaderException ();
                    Form quoteTarget = this.Read ();
                    if (quoteTarget.CanFollowQuote)
                        quoted.Add (quoteTarget);
                    else
                        throw new ReaderException ();

                    if (!quoteTarget.IsNoise)
                        return new UnquoteForm (commaStart, quoted.ToArray ());
                }
            }
        }

        public Form Read ()
        {
            if (this.AtEndOfFile ())
                return null;

            char peeked = (this.PeekChar());
            if (peeked == ';')
                return ReadComment (this.FilePos);
            else if (peeked == ' ' || peeked == '\r')
                return ReadWhitespace (this.FilePos);
            else if (peeked == '#')
                return ReadSharp (this.FilePos);
            else if (peeked == '\'')
                return ReadSingleQuote (this.FilePos);
            else if (peeked == '`')
                return ReadBackQuote (this.FilePos);
            else if (peeked == '(')
                return ReadList (this.FilePos);
            else if (peeked == '.')
                return ReadDot ();
            else if (peeked == ',')
                return ReadComma (this.FilePos);
            else if (IsSymbolInitial (peeked))
                return ReadSymbol (FilePos);

            else
                throw new ReaderBadCharacterException (peeked, this.FilePos);
        }
    }
}
From: Emre Sevinc
Subject: Re: [OT] S-expression parser in C#?
Date: 
Message-ID: <87wtn54319.fsf@ileriseviye.org>
"Jamie Border" <·····@jborder.com> writes:

> Tangentially CL-related, I guess:
>
> Anybody know of a good(ish) example of this?
>
> I've just hand-rolled a reasonable (but slowish) s-exp parser in C#, but I'm 
> not happy with the result (slow).

I don't how good it is, but a simple example from Microsoft
itself:


http://groups-beta.google.com/group/comp.lang.lisp/browse_frm/thread/fbcb4d5d9e791f47/4fab4a982b1cedd0



-- 
Emre Sevinc

eMBA Software Developer         Actively engaged in:
http:www.bilgi.edu.tr           http://ileriseviye.org
http://www.bilgi.edu.tr         http://fazlamesai.net
Cognitive Science Student       http://cazci.com
http://www.cogsci.boun.edu.tr