首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当使用Sprache解析文本时,我可以确定原始字符串中的当前索引吗?

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

Stack Overflow用户
提问于 2019-07-20 00:38:55
回答 2查看 474关注 0票数 1

我让set来解析一个方程,其中包含了许多不同的方法调用。在解析该方法之后,是否有方法确定原始字符串中的索引值?也许Parse有一个“当前索引”值和“长度”值,这是可以访问的吗?

示例输入字符串:

代码语言:javascript
复制
IndexOf("fred", 2) + IndexOf("bob")

使用这样的解析器..。

代码语言:javascript
复制
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)吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-22 18:50:25

我已经回答了我自己的问题。定位()解析器扩展调用允许解析器跟踪原始文本中的位置。

代码语言:javascript
复制
  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类来保存职位信息,这是来自于西普的MethodPosAware

代码语言:javascript
复制
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; }
}

我认为我将进一步扩展它,以处理不仅仅是方法名称,但这足以回答我的问题。我希望这能帮上一个人。

票数 1
EN

Stack Overflow用户

发布于 2019-08-22 07:01:52

如果使用泛型类和扩展方法,则可以使用更通用的方法。

代码语言:javascript
复制
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();
}

使用它:

代码语言:javascript
复制
from c in Parse.Char('a').WithPosition()
select (c.Start, c.Value)

from c in Parameter.DelimitedBy(ListDelimiter).WithPosition()
select (c.Start, c.Value)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57120923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档