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