c# - 如何改进缺少右大括号的 Sprache 解析器错误消息?

标签 c# parsing sprache

我正在使用 Sprache 构建一个简单的命令式语法。我正在尝试找出是否有一种方法可以在缺少结束字符(例如 ]、, })时获得更好的错误报告。

如果缺少结束字符,我的语法会正确报告错误。然而,消息传递导致难以理解真正的问题。给定以下要解析的字符串:

求和 10 [乘以 5 4

Sprache 报告以下错误:

Sprache.ParseException:解析失败:意外的“[”;预期的换行符或输入结尾(第 1 行,第 8 列);最近消费:总和 10

似乎正在发生的事情是,解析器试图匹配我的 CommandSubstitution,但未能找到结束的 ']'。这会导致解析器回退并尝试替代。由于它无法再为命令匹配任何 Things,因此它会尝试匹配 CommandTerminator。由于无法匹配 '[',它会报告错误,提示预期的 newlineend of input 而不是说,“嘿,伙计,你没有匹配你的牙套!”

对于如何改进语法以使用像 Sprache 这样的解析库来更好地报告,是否有任何解决方法或建议?

public static readonly Parser<Word> Word = Parse.Char(IsWordChar, "word character").AtLeastOnce().Text()
                                                .Select(str => new Word(str));

public static readonly Parser<CommandSubstitution> CommandSubstitution = from open in Parse.Char('[').Once()
                                                                            from body in Parse.Ref(() => Things)
                                                                            from close in Parse.Char(']').Once()
                                                                            select new CommandSubstitution(body.ToList());


public static readonly Parser<Thing> Thing = CommandSubstitution.Or<Thing>(Word);

public static readonly Parser<IEnumerable<Thing>> Things = (from ignoreBefore in WordSeparator.Optional()
                                                            from thing in Thing
                                                            from ignoreAfter in WordSeparator.Optional()
                                                            select thing).Many();

public static readonly Parser<IEnumerable<Thing>> Command = from things in Things
                                                            from terminator in CommandTerminator
                                                            select things;

最佳答案

听起来总体问题是 Sprache 正在失败,尝试替代方案,然后再次失败,而它应该在第一次失败后放弃。

您正在使用 Parse.Many 扩展方法定义 Things 解析器。 Parse.Many 解析器的特点是它总是成功,无论其内部解析器是成功还是失败。如果内部解析器失败,Parse.Many 会简单地假设没有更多的输入需要处理。

这似乎就是这里发生的事情。首先,Parse.Many 使用片段 "sum 10 "。然后它尝试解析更多输入,但失败了。由于它无法解析更多输入,因此它假定不再需要使用更多输入。但是随后会出现错误,因为片段 [multiply 5 4 尚未被使用。

要解决此问题,请使用 Parse.XMany 而不是 Parse.Many。如果Parse.XMany 的内部解析器在消耗至少一个字符后 失败,则Parse.XMany 将立即放弃并报告失败。

关于c# - 如何改进缺少右大括号的 Sprache 解析器错误消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37778472/

相关文章:

c# - 如何在bho中的异步httpwebrequest回调中访问ui线程

c# - Windows BluetoothLeAdvertisement 不包含 Android 设备广播的服务 uuid

java - 基于正则表达式用Java添加html标签,保持数据匹配

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

c# - 将 SQL 查询中的参数投影到对象中

c# - 无法引用 Microsoft.Device 命名空间

java - "intelligently"解析用户输入参数

c - 在嵌入式系统上解析字符串的有效方法是什么?

c# - Sprache DelimitBy 换行

c# - Sprache 中的递归表达式解析