S表达式解析 [英] S-Expressions parsing

查看:145
本文介绍了S表达式解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了此问题今天早些时候:

I ran into this question earlier today:


示例输入: 和吉尔,然后我们去购物

示例输出: [TOP [S [S [NP [PRP I]]] [VP [VBD ran] [PP [IN成] [NP [NNP Joe] [CC和] [NNP Jill]]]]] [CC和] [S [ADVP [RB
然后]] [NP [PRP我们]] [VP [VBD去了[NP [NN购物]]]]]]]

Example Input: I ran into Joe and Jill and then we went shopping
Example Output: [TOP [S [S [NP [PRP I]] [VP [VBD ran] [PP [IN into] [NP [NNP Joe] [CC and] [NNP Jill]]]]] [CC and] [S [ADVP [RB then]] [NP [PRP we]] [VP [VBD went] [NP [NN shopping]]]]]]

我只是建议简单地解析预期的输出(因为它看起来像一个s -expression)转换成一个对象(在我们的例子中是一棵树),然后使用简单的LINQ方法对其进行处理。但是,令我惊讶的是,我找不到C#s表达式解析器。

I was about to suggest simply parsing the expected output (as it looks like an s-expression) into an object (in our case a tree) and then using simple LINQ methods to process it. However, to my surprise, I was unable to find a C# s-expression parser.

我唯一想到的就是使用Clojure对其进行解析,因为它可以编译为clr,但我不确定这是否是一个好的解决方案。

The only thing I could think of is using Clojure to parse it since it compiles to the clr, I'm not sure it's a good solution though.

顺便说一句,我不介意 dynamic 类型的输出的答案。

By the way, I don't mind the answer to output of type dynamic. Only answers I've found here were for deserializing into a specific schema.

总结一下我的问题:
我需要反序列化s-表达式在C#中(对以后的问题的读者来说,序列化会很好)

To sum up my question: I need to deserialize s-expressions in C# (serialization would be nice for future readers of this question)

推荐答案

似乎您需要一个数据形式的结构:

It looks like you need a data-structure of the form:

public class SNode
{
    public String Name { get; set; }

    private readonly List<SNode> _Nodes = new List<SNode>();
    public ICollection<SNode> Nodes { get { return _Nodes; } }
}

以下格式的序列化器

public String Serialize(SNode root)
{
    var sb = new StringBuilder();
    Serialize(root, sb);
    return sb.ToString();
}

private void Serialize(SNode node, StringBuilder sb)
{
    sb.Append('(');

    sb.Append(node.Name);

    foreach (var item in node.Nodes)
        Serialize(item, sb);

    sb.Append(" )");
}

以及以下格式的反序列化器:

And a de-serializer of the form:

public SNode Deserialize(String st)
{
    if (String.IsNullOrWhiteSpace(st))
        return null;

    var node = new SNode();

    var nodesPos = String.IndexOf('(');
    var endPos = String.LastIndexOf(')');

    var childrenString = st.SubString(nodesPos, endPos - nodesPos);

    node.Name = st.SubString(1, (nodesPos >= 0 ? nodePos : endPos)).TrimEnd();

    var childStrings = new List<string>();

    int brackets = 0;
    int startPos = nodesPos;
    for (int pos = nodesPos; pos++; pos < endPos)
    {
        if (st[pos] == '(')
            brackets++;
        else if (st[pos] == ')')
        {
            brackets--;

            if (brackets == 0)
            {
                childStrings.Add(st.SubString(startPos, pos - startPos + 1));
                startPos = pos + 1;
            }
        }
    }

    foreach (var child in childStrings)
    {
        var childNode = Deserialize(this, child);
        if (childNode != null)
            node.Nodes.Add(childNode);
    }

    return node;
}

如果尚未测试甚至未编译此代码,则更多甚至更少。

If haven't tested or even compiled this code, however, this is more or less how it could work.

这篇关于S表达式解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆