2016-08-23 78 views
0

我试图创建一个Sprache解析器,其中输入的部分应该被解析成一个字典名单汇总到字典

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

and=a;list=of;arbitrary=key;value=pairs部分应该在字典<字符串结束,串>。
为此,我已经

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)) 

或类似的东西。
我该如何解析字典中的任意键=值[;]对?

回答

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 
} 
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"); 
}