構文解析器のSpracheで0回または1回出現するOptionalな文字列を読み取るメソッド一覧について説明します。
Optional()
Parserがオプションであることを示します。 Parserは読み取りが成功するか失敗するかに関わらず、常に成功を返すようになります。 なお、マッチに失敗した場合は IOption 型が返ってくるため、.GetOrDefault() で結果を取り出します。
Parser<IOption<T>> Optional<T>(this Parser<T> parser)
Parser<string> identifier = Parse.Identifier(Parse.Letter, Parse.LetterOrDigit);
Parser<string> label =
from labelName in identifier.Token()
from colon in Parse.Char(':').Token()
select labelName;
Parser<Tuple<string, string[]>> instruction =
from instructionName in Parse.LetterOrDigit.Many().Text().Token()
from operands in identifier.Token().XDelimitedBy(Parse.Char(','))
select Tuple.Create(instructionName, operands.ToArray());
// Example of returning anonymous type from a sprache parser
var assemblyLine =
from l in label.Optional()
from i in instruction.Optional()
select new {Label = l, Instruction = i};
Assert.Equal("test", assemblyLine.Parse("test: mov ax, bx").Label.Get());
Assert.False(assemblyLine.Parse("mov ax, bx").Label.IsDefined);
XOptional()
Optionalの排他的 (eXclusive) 版です。
Parser<IOption<T>> XOptional<T>(this Parser<T> parser)
Parser<string> identifier = Parse.Identifier(Parse.Letter, Parse.LetterOrDigit);
Parser<string> label =
from labelName in identifier.Token()
from colon in Parse.Char(':').Token()
select labelName;
// unexpected 'l'; expected :
Assert.Throws<ParseException>(() => label.XOptional().Parse("invalid label:"));
以上です。