0

我正在尝试创建一个Sprache解析器,其中应将部分输入解析为字典

input=some/fixed/stuff;and=a;list=of;arbitrary=key;value=pairs

and=a;list=of;arbitrary=key;value=pairs部分应该以 Dictionary<string,string> 结尾。
为此我有

    public static Parser<string> Key = Parse.CharExcept('=').Many().Text();
    public static Parser<string> Value = Parse.CharExcept(';').Many().Text();

    public static Parser<KeyValuePair<string, string>> ParameterTuple =
        from key in Key
        from eq in Parse.Char('=')
        from value in Value
        select new KeyValuePair<string, string>(key, value);

和扩展方法

    public static IEnumerable<T> Cons<T>(this T head, IEnumerable<T> rest)
    {
        yield return head;
        foreach (var item in rest)
            yield return item;
    }

    public static Parser<IEnumerable<T>> ListDelimitedBy<T>(this Parser<T> parser, char delimiter)
    {
        return
            from head in parser
            from tail in Parse.Char(delimiter).Then(_ => parser).Many()
            select head.Cons(tail);
    }

(从示例中复制)

然后我尝试了

public static Parser<IEnumerable<KVP>> KeyValuePairList = KVPair.ListDelimitedBy(';'); // KVP is just an alias for KeyValuePair<string,string>

现在我被困在如何做类似的事情上

public static Parser<???> Configuration =
        from fixedstuff in FixedStuff
        from kvps in Parse.Char(';').Then(_ => KeyValuePairList)
        select new ???(fixedstuff, MakeDictionaryFrom(kvps))

或类似的东西。
我如何将任意 key=value[;] 对解析为字典?

4

2 回答 2

0

你是这个意思吗?

public static Parser<string> Key = Parse.CharExcept('=').Many().Text();
public static Parser<string> Value = Parse.CharExcept(';').Many().Text();

public static Parser<KeyValuePair<string, string>> ParameterTuple =
    from key in Key
    from eq in Parse.Char('=')
    from value in Value
    select new KeyValuePair<string, string>(key, value);

public static Parser<string> FixedStuff = Parse.String("input=some/fixed/stuff").Text();

public static Parser<Config> Configuration =
    from fixedStuff in FixedStuff
    from _ in Parse.Char(';')
    from kvps in ParameterTuple.DelimitedBy(Parse.Char(';'))
    select new Config(fixedStuff, kvps.ToDictionary(x => x.Key, x => x.Value));

public class Config
{
    public Config(string fixedStuff, IReadOnlyDictionary<string, string> dict)
    {
        FixedStuff = fixedStuff;
        Dict = dict;
    }

    public string FixedStuff { get; }
    public IReadOnlyDictionary<string, string> Dict { get; }
}

[Fact]
public void ParseIt()
{
    Configuration.Parse("input=some/fixed/stuff;and=a;list=of;arbitrary=key;value=pairs");
}
于 2016-08-23T17:18:11.467 回答
0

实际上,从任何 IEnumerable 中制作字典非常容易,只要确保包含 System.Linq。这实际上只是查询是否正确并理解它的问题,在你的情况下是实际的字符串解析,所以我把它留给你。以下代码构建了一个字典,您只需要提供字符串和解析。

//If the parse is simple it can be done inline with the dictionary creation
private string GenerateKey(string fullString)
{
   //parse key from original string and return
}

//If the parse is simple it can be done inline with the dictionary creation
private string GenerateValue(string fullString)
{
     //Parse Values from your original string and return
}


private void UsageMethod(IEnumerable<fullString> sprachs)
{
      var dictionary = sprachs.ToDictionary(
                              fString => GenerateKey(fString), //The Key
                              fString => GenerateValue(fString) //The Value
                       );

      //Now you can use Dicitonary as it is a IDictionary<string,string>
      // so it too can be overriden an extended if need be
}
于 2016-08-23T17:30:43.123 回答