首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Sprache解析标识符的Enum?

用Sprache解析标识符的Enum?
EN

Stack Overflow用户
提问于 2015-09-21 16:08:22
回答 2查看 734关注 0票数 2

我开始使用Sprache来解析特定于领域的数学表达式语言。我知道我可以使用这样的方法来解析标识符:

代码语言:javascript
复制
    static readonly Parser<string> Identifier = 
        from leading in Parse.WhiteSpace.Many()
        from first in Parse.Letter.Once()
        from rest in Parse.LetterOrDigit.Many()
        from trailing in Parse.WhiteSpace.Many()
        select new string(first.Concat(rest).ToArray());

由此,我希望构建一个解析器,只有当标识符令牌是Enum的文本值之一时,解析器才会成功。因此,假设我有一个名为维度的Enum,其值为Dimension.Location和Dimension.Time。我想做

代码语言:javascript
复制
    static readonly Parser<Dimension> DimensionIdentifier = ...

只有在正在解析的标识符和标识符的令牌字符串是枚举名称之一(“位置”或“时间”)并分别返回枚举值Dimension.Location或Dimension.Time的情况下,才能成功。有人能帮上忙吗?也许是个简单的问题?谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-21 18:07:14

很好的解决办法从这里偷来的。http://www.codewise-llc.com/blog/2015/8/13/parsing-enum-values-with-sprache

构建一个类型化的助手类来构建给定枚举的解析器.

代码语言:javascript
复制
public static class EnumParser<T>
{
    public static Parser<T> Create()
    {
        var names = Enum.GetNames(typeof(T));

        var parser = Parse.IgnoreCase(names.First()).Token()
            .Return((T)Enum.Parse(typeof(T), names.First()));

        foreach (var name in names.Skip(1))
        {
            parser = parser.Or(Parse.IgnoreCase(name).Token().Return((T)Enum.Parse(typeof(T), name)));
        }

        return parser;
    }
}

那么你的解析器就是这样..。

代码语言:javascript
复制
public static Parser<Dimension> Dimension = EnumParser<Dimension>.Create();

和一些单元测试(将类名更改为您正在使用的任何名称,我正在使用some教程来开始).

代码语言:javascript
复制
 [Test]
        [TestCase("Time", Dimension.Time)]
        [TestCase("Location", Dimension.Location)]
        public void ShouldGetProperEnumValue(string enumValueName, Dimension expected)
        {
            var eValue = QuestionnaireGrammar.Dimension.Parse(enumValueName);
            Assert.AreEqual(expected, eValue);
        }

        [Test]
        [ExpectedException]
        [TestCase("Fredo")]
        public void ShouldFailIfNotInList(string enumValueName)
        {
            var eValue = QuestionnaireGrammar.Dimension.Parse(enumValueName);
        }

有趣的图书馆,很高兴了解到它。

好吧,很容易连锁解析器..。

创建了身份解析器的副本,并将其命名为Identifier2以保持其清晰.

代码语言:javascript
复制
  public static readonly Parser<string> Identifier2 =
            from leading in Parse.WhiteSpace.Many()
            from first in Parse.Letter.Once()
            from rest in Parse.LetterOrDigit.Many()
            from trailing in Parse.WhiteSpace.Many()
            select new string(first.Concat(rest).ToArray());

然后添加了一个复合解析器,该解析器接收Identifier2解析器的结果并使用维度解析器.

代码语言:javascript
复制
 public  static readonly Parser<Dimension> IdentityDimension =
            from result in Identifier2
            select Dimension.Parse(result);

虽然不确定您正在购买什么- enum解析器似乎已经完成了标识符解析器所做的一切。

票数 0
EN

Stack Overflow用户

发布于 2018-05-13 18:09:25

我使用以下方法:

代码语言:javascript
复制
public static Parser<TEnum> ParseEnum()
{
    return Enum.GetValues(typeof(TEnum))
        .Cast<TEnum>()
        .Select(value => Parse.IgnoreCase(Enum.GetName(typeof(TEnum), value)).Return(value))
        .Aggregate((x, y) => x.Or(y));
}

它与dbugger's answer类似,因为它仍然是基于Parse.Or的,但它的编写方式更加实用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32699833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档