Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在使用Sprache解析文本时,我可以确定原始字符串中的当前索引吗?_C#_Parsing_Sprache - Fatal编程技术网

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

C# 在使用Sprache解析文本时,我可以确定原始字符串中的当前索引吗?,c#,parsing,sprache,C#,Parsing,Sprache,我已经设置了Sprache来解析一个等式,其中包含许多不同的可能方法调用。解析方法后,是否有方法确定原始字符串中的索引值?也许解析有一个“当前索引”值和“长度”值,可以通过某种方式访问 输入字符串示例: IndexOf("fred", 2) + IndexOf("bob") 使用这样的解析器 Parser<Expression> FunctionCall = from namePart in Parse.Letter.Many().Text()

我已经设置了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());
Parser FunctionCall=来自Parse.Letter.Many().Text()中的namePart
来自Parse.Char(“(”)中的lparen
from expr in Parameter.DelimitedBy(ListDelimiter)
来自Parse.Char(')中的rparen
选择CallMethod(namePart,可枚举。重复(sourceData,1)
.Concat(expr)
.ToArray());

有谁能想出一个“窍门”让我确定第一个CallMethod处理原始字符串中的子字符串(0,18),第二个CallMethod处理子字符串(21,14)。它是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));
Parser FunctionCall=(来自Parse.Letter.Many().Text()中的namePart)
来自Parse.Char(“(”)中的lparen
from expr in Parameter.DelimitedBy(ListDelimiter)
来自Parse.Char(')中的rparen
选择new MethodPosAware(namePart,expr)).Posited()
.Select(x=>CallMethod(x.Value,可枚举。重复(sourceData,1)
.Concat(x.Params)
.ToArray(),
x、 位置,x.长度);
我必须创建一个新的MethodPosAware类来保存位置信息,它来自Sprache的iPositonWare

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; }
}
class MethodPosAware:iPositonWare
{
public MethodPosAware(string methodName,IEnumerable参数)
{
Value=methodName;
参数=参数;
}
public MethodPosAware SetPos(位置起始点,整数长度)
{
Pos=startPos;
长度=长度;
归还这个;
}
公共位置Pos{get;set;}
公共整数长度{get;set;}
公共字符串值{get;set;}
公共IEnumerable参数{get;set;}
}

我想我将进一步扩展它,使其不仅仅适用于方法名,但现在这足以回答我的问题。我希望这对以后的人有所帮助。

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

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)