我开始使用Sprache来解析特定于领域的数学表达式语言。我知道我可以使用这样的方法来解析标识符:
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。我想做
static readonly Parser<Dimension> DimensionIdentifier = ...只有在正在解析的标识符和标识符的令牌字符串是枚举名称之一(“位置”或“时间”)并分别返回枚举值Dimension.Location或Dimension.Time的情况下,才能成功。有人能帮上忙吗?也许是个简单的问题?谢谢!
发布于 2015-09-21 18:07:14
很好的解决办法从这里偷来的。http://www.codewise-llc.com/blog/2015/8/13/parsing-enum-values-with-sprache
构建一个类型化的助手类来构建给定枚举的解析器.
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;
}
}那么你的解析器就是这样..。
public static Parser<Dimension> Dimension = EnumParser<Dimension>.Create();和一些单元测试(将类名更改为您正在使用的任何名称,我正在使用some教程来开始).
[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以保持其清晰.
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解析器的结果并使用维度解析器.
public static readonly Parser<Dimension> IdentityDimension =
from result in Identifier2
select Dimension.Parse(result);虽然不确定您正在购买什么- enum解析器似乎已经完成了标识符解析器所做的一切。
发布于 2018-05-13 18:09:25
我使用以下方法:
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的,但它的编写方式更加实用。
https://stackoverflow.com/questions/32699833
复制相似问题