1
我正在嘗試使用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);
}
}
生產
嘗試一個public 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