# 分析器组合子

Ted Neward

## 简单的语言

(指出只需将所有字母转换为数字方式不完全兼容的解决方案，要求我墨守成规的人。在大学，正是共同在尝试来阐明"酷"的电话号码的朋友圈 — — 一个前室友仍在等待 1-800-CTHULHU 成为免费的事实上，所以他可以赢得这场比赛，永远在一起。)

``````class PhoneNumber
{
public string AreaCode { get; set; }
public string Prefix { get; set; }
public string Line { get; set; }
}
``````

``````public static Parser<string> numberParser =
Parse.Digit.AtLeastOnce().Text();
``````

``````[TestMethod]
public void ParseANumber()
{
string result = numberParser.Parse("101");
Assert.AreEqual("101", result);
}
[TestMethod]
public void FailToParseANumberBecauseItHasTextInIt()
{
string result = numberParser.TryParse("abc").ToString();
Assert.IsTrue(result.StartsWith("Parsing failure"));
}
``````

``````public static Parser<string> threeNumberParser =
Parse.Numeric.Then(first =>
Parse.Numeric.Then(second =>
Parse.Numeric.Then(third =>
Parse.Return(first.ToString() +
second.ToString() + third.ToString()))));
``````

``````[TestMethod]
public void ParseJustThreeNumbers()
{
string result = threeNumberParser.Parse("123");
Assert.AreEqual("123", result);
}
[TestMethod]
public void ParseJustThreeNumbersOutOfMore()
{
string result = threeNumberParser.Parse("12345678");
Assert.AreEqual("123", result);
}
[TestMethod]
public void FailToParseAThreeDigitNumberBecauseItIsTooShort()
{
var result = threeNumberParser.TryParse("10");
Assert.IsTrue(result.ToString().StartsWith("Parsing failure"));
}
``````

``````public static Parser<string> fourNumberParser =
Parse.Numeric.Then(first =>
Parse.Numeric.Then(second =>
Parse.Numeric.Then(third =>
Parse.Numeric.Then(fourth =>
Parse.Return("" + first.ToString() +
second.ToString() + third.ToString() +
fourth.ToString())))));
public static Parser<string> areaCodeParser =
(from number in threeNumberParser
select number).
XOr(
from lparens in Parse.Char('(')
from number in threeNumberParser
from rparens in Parse.Char(')')
select number);
public static Parser<PhoneNumber> phoneParser =
(from areaCode in areaCodeParser
from _1 in Parse.WhiteSpace.Many().Text()
from prefix in threeNumberParser
from _2 in (Parse.WhiteSpace.Many().Text()).
Or(Parse.Char('-').Many())
from line in fourNumberParser
select new PhoneNumber() { AreaCode=areaCode, Prefix=prefix, Line=line});
Using the parser becomes pretty straightforward at this point:
[TestMethod]
public void ParseAFullPhoneNumberWithSomeWhitespace()
{
var result = phoneParser.Parse("(425) 647-4526");
Assert.AreEqual("425", result.AreaCode);
Assert.AreEqual("647", result.Prefix);
Assert.AreEqual("4526", result.Line);
}
``````

## 组合数学概念

Ted Neward Neudesic LLC 建筑顾问。 他已写了一百多篇和编著或合著了十几本书，包括"专业 F # 2.0"（Wrox，2010年）。 他是 C# MVP，在世界各地的会议上发言。 他咨询、 定期指导 — — 达到他在 ted@tedneward.comTed.Neward@neudesic.com 如果你有兴趣，让他来和你的团队，工作或阅读他的博客，在 blogs.tedneward.com