为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
慕沐林林 2023-07-09 15:06:29
我设置了 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) ?
查看完整描述

2 回答

?
开满天机

TA贡献1786条经验 获得超13个赞

如果您使用通用类和扩展方法,您可以采用更通用的方法


public class PositionAware<T> : IPositionAware<PositionAware<T>>

{

    public PositionAware(T value)

    {

        Value = value;

    }


    public T Value { get; }

    public Position Start { get; private set; }

    public int Length { get; private set; }

    public PositionAware<T> SetPos(Position startPos, int length)

    {

        Start = startPos;

        Length = length;

        return this;

    }


}

public static Parser<PositionAware<T>> WithPosition<T>(this Parser<T> value)

{

    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)


查看完整回答
反对 回复 2023-07-09
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

我已经设法回答我自己的问题。这是 Positioned() 解析器扩展调用,允许解析器跟踪原始文本中的位置。


  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 new MethodPosAware(namePart, expr)).Positioned()

                            .Select(x => CallMethod(x.Value, Enumerable.Repeat(sourceData, 1)

                                        .Concat(x.Params)

                                        .ToArray(),

                                        x.Pos.Pos, x.Length));

我必须创建一个新的MethodPosAware类来保留位置信息,该信息源自 Sprache 的IPositionAware:


class MethodPosAware : IPositionAware<MethodPosAware>

{

    public MethodPosAware(string methodName, IEnumerable<Expression> parameters)

    {

        Value = methodName;

        Params = parameters;

    }


    public MethodPosAware SetPos(Position startPos, int length)

    {

        Pos = startPos;

        Length = length;

        return this;

    }


    public Position Pos { get; set; }

    public int Length { get; set; }

    public string Value { get; set; }

    public IEnumerable<Expression> Params { get; set; }

}

我想我将进一步扩展它以不仅仅使用方法名称,但这足以回答我现在的问题。我希望这可以帮助某人。


查看完整回答
反对 回复 2023-07-09
  • 2 回答
  • 0 关注
  • 106 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信