使用 Sprache 解析文本时,我可以确定原始字符串中的当前索引吗?

我设置了 Sprache 来解析一个方程,该方程中有许多不同的可能的方法调用。解析方法后,有没有办法确定原始字符串中的索引值?也许解析有一个可以以某种方式访问的“当前索引”值和“长度”值?


输入字符串示例:


IndexOf("fred", 2) + IndexOf("bob")

使用这样的解析器...


Parser<Expression> FunctionCall = from namePart in Parse.Letter.Many().Text()

                       from lparen in Parse.Char('(')

                       from expr in Parameter.DelimitedBy(ListDelimiter)

                       from rparen in Parse.Char(')')

                       select CallMethod(namePart, Enumerable.Repeat(sourceData, 1)

                                                             .Concat(expr)

                                                             .ToArray());

谁能想到一个“技巧”,让我能够确定第一个 CallMethod 处理SubString(0, 18),第二个 CallMethod 处理原始字符串中的SubString(21, 14) ?


慕沐林林
浏览 107回答 2
2回答

开满天机

如果您使用通用类和扩展方法,您可以采用更通用的方法public class PositionAware<T> : IPositionAware<PositionAware<T>>{&nbsp; &nbsp; public PositionAware(T value)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Value = value;&nbsp; &nbsp; }&nbsp; &nbsp; public T Value { get; }&nbsp; &nbsp; public Position Start { get; private set; }&nbsp; &nbsp; public int Length { get; private set; }&nbsp; &nbsp; public PositionAware<T> SetPos(Position startPos, int length)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Start = startPos;&nbsp; &nbsp; &nbsp; &nbsp; Length = length;&nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; }}public static Parser<PositionAware<T>> WithPosition<T>(this Parser<T> value){&nbsp; &nbsp; return value.Select(x => new PositionAware<T>(x)).Positioned();}使用它:from c in Parse.Char('a').WithPosition()select (c.Start, c.Value)from c in Parameter.DelimitedBy(ListDelimiter).WithPosition()select (c.Start, c.Value)

慕无忌1623718

我已经设法回答我自己的问题。这是 Positioned() 解析器扩展调用,允许解析器跟踪原始文本中的位置。&nbsp; Parser<Expression> FunctionCall = (from namePart in Parse.Letter.Many().Text()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from lparen in Parse.Char('(')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from expr in Parameter.DelimitedBy(ListDelimiter)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from rparen in Parse.Char(')')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; select new MethodPosAware(namePart, expr)).Positioned()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(x => CallMethod(x.Value, Enumerable.Repeat(sourceData, 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Concat(x.Params)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .ToArray(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x.Pos.Pos, x.Length));我必须创建一个新的MethodPosAware类来保留位置信息,该信息源自 Sprache 的IPositionAware:class MethodPosAware : IPositionAware<MethodPosAware>{&nbsp; &nbsp; public MethodPosAware(string methodName, IEnumerable<Expression> parameters)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Value = methodName;&nbsp; &nbsp; &nbsp; &nbsp; Params = parameters;&nbsp; &nbsp; }&nbsp; &nbsp; public MethodPosAware SetPos(Position startPos, int length)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Pos = startPos;&nbsp; &nbsp; &nbsp; &nbsp; Length = length;&nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; }&nbsp; &nbsp; public Position Pos { get; set; }&nbsp; &nbsp; public int Length { get; set; }&nbsp; &nbsp; public string Value { get; set; }&nbsp; &nbsp; public IEnumerable<Expression> Params { get; set; }}我想我将进一步扩展它以不仅仅使用方法名称,但这足以回答我现在的问题。我希望这可以帮助某人。
打开App,查看更多内容
随时随地看视频慕课网APP