私はSpracheパーサーコンビネータライブラリを使用して小さなパーサーを作成しようとしています。パーサは、\
という単一の行で終わる行を無視できる空白として解析できる必要があります。パーサーコンビネータを使用して '行継続'を処理する方法
質問
どのように行継続文字\
が含まれていてもよい=
記号の後の値を解析できるパーサを作成することができますか?例
a = b\e,\
c,\
d
については は(KeyValuePair (Key, 'a'), (Value, 'b\e, c, d'))
として解析されなければなりません。
このライブラリとパーサーコンビネータを一般的に使用するのは初めてです。したがって、正しい方向のポインタは非常に高く評価されています。私が試してみました何
テスト
public class ConfigurationFileGrammerTest
{
[Theory]
[InlineData("x\\\n y", @"x y")]
public void ValueIsAnyStringMayContinuedAccrossLinesWithLineContinuation(
string input,
string expectedKey)
{
var key = ConfigurationFileGrammer.Value.Parse(input);
Assert.Equal(expectedKey, key);
}
}
生産
試み1public static readonly Parser<string> Value =
from leading in Parse.WhiteSpace.Many()
from rest in Parse.AnyChar.Except(Parse.Char('\\')).Many()
.Or(Parse.String("\\\n")
.Then(chs => Parse.Return(chs))).Or(Parse.AnyChar.Except(Parse.LineEnd).Many())
select new string(rest.ToArray()).TrimEnd();
テスト出力
Xunit.Sdk.EqualException: Assert.Equal() Failure
↓ (pos 1)
Expected: x y
Actual: x\
↑ (pos 1)
試み2 あなたが出力に行継続を含めることはできません
public static readonly Parser<string> SingleLineValue =
from leading in Parse.WhiteSpace.Many()
from rest in Parse.AnyChar.Many().Where(chs => chs.Count() < 2 || !(string.Join(string.Empty, chs.Reverse().Take(2)).Equals("\\\n")))
select new string(rest.ToArray()).TrimEnd();
public static readonly Parser<string> ContinuedValueLines =
from firsts in ContinuedValueLine.AtLeastOnce()
from last in SingleLineValue
select string.Join(" ", firsts) + " " + last;
public static readonly Parser<string> Value = SingleLineValue.Once().XOr(ContinuedValueLines.Once()).Select(s => string.Join(" ", s));
テスト出力
Xunit.Sdk.EqualException: Assert.Equal() Failure
↓ (pos 1)
Expected: x y
Actual: x\\n y
↑ (pos 1)
あなたが私の答えを見ていましたか? – amirouche