[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [computer-go] SGF parsers



Mark wrote:
> P.S. In my search for definitions of SGF, I came upon an example with merged
> games. That seems to unnecessarily complicate things, is it widely used?

I've come across such files a few times but it seems easier to split
them externally than handle them internally anyway.

> as making a full SGF reader seems like a considerable amount of
> work.

It's not very hard, at least not in programming languages with sane
string support. I won't guarantee the correctness of the code below
(it doesn't handle every newline convention at least) but it has
worked well enough for me.

Basically read_property() and read() are methods in an SgfNode class
which is used to build an sgf tree. The main parsing, including
recursion, is in the read() method.

/Gunnar

string read_property(string name, string sgfdata)
{
    string value = "";
    int quoted = 0;
    while (sgfdata != "")
    {
        string c = sgfdata[0..0];
        sgfdata = sgfdata[1..];
        if (quoted)
        {
            if (value != "\n")
                value += c;
            quoted = 0;
        }
        else if (c == "\\")
            quoted = 1;
        else if (c == "]")
        {
            add_property(name, value);
            return sgfdata;
        }
        else
            value += c;
    }
    werror("Unexpected end of sgf data.\n");
    return sgfdata;
}

string read(string sgfdata)
{
    string property_name = "";
    int variation = 0;
    while (sgfdata != "")
    {
        string c = sgfdata[0..0];
        if (c >= "A" && c <= "Z")
            sscanf(sgfdata, "%[A-Z]%s", property_name, sgfdata);
        else if (c == "[")
            sgfdata = read_property(property_name, sgfdata[1..]);
        else if (c == "(")
        {
            variation = 1;
            sgfdata = sgfdata[1..];
        }
        else if (c == ")")
            return sgfdata[1..];
        else if (c == ";")
        {
            SgfNode child = SgfNode(this_object());
            if (!variation)
                return child->read(sgfdata[1..]);
            else
                sgfdata = child->read(sgfdata[1..]);
        }
        else if (c == " " || c == "\t" || c == "\v" || c == "\n")
            sgfdata = sgfdata[1..];
        else
        {
            werror("Warning: Skipping unexpected character %s.\n", c);
            sgfdata = sgfdata[1..];
        }
    }
    werror("Unexpected end of sgf data.\n");
    return sgfdata;
}
_______________________________________________
computer-go mailing list
computer-go@xxxxxxxxxxxxxxxxx
http://www.computer-go.org/mailman/listinfo/computer-go/