ParseKit的开发者在这里。
ParseKit 中有两个功能可用于帮助提供用户可读的提示,描述输入中遇到的解析错误。
-[PKParser bestMatchFor:]
PKTrack
班级_
听起来您知道该-bestMatchFor:
方法,即使在这种情况下它没有按照您的预期进行。
我认为这PKTrack
门课在这里会更有帮助。正如Metsker的书中所描述的,除了它的子解析器是必需的,并且当它的所有子解析器都不匹配时,会抛出一个错误(带有有用的错误消息)。PKTrack
PKSequence
因此,这是您的示例输入的语法:
@start = '(' expr ')' | expr;
expr = ('+' | '-') term term;
term = '(' expr ')' | Word;
任何连续列出的作品都是一个序列——但也可以是一个轨道。
将这些 Sequences 更改为 Tracks 的好处是,NSException
如果输入不匹配,则会抛出人类可读的解析错误消息。缺点是您现在必须将工厂生成的解析器的所有用法包装在一个 try/catch 块中以捕获这些 Track 异常。
当前(或至少在此之前)的问题是PKParserFactory
从未使用 Tracks 生成解析器。相反,它总是使用序列。
所以我刚刚在谷歌代码的主干头中添加了一个新选项(你需要更新)。
#define USE_TRACK 0
在
PKParserFactory.m
0
默认情况下。如果将此定义更改为1
,将使用轨道而不是序列。所以给定上面的语法和这样的无效输入:
(+ a - b c))
这个客户代码:
NSString *g = // fetch grammar above
PKParser *p = [[PKParserFactory factory] parserFromGrammar:g assembler:self];
NSString *s = @"(+ a - b c))";
@try {
PKAssembly *res = [p parse:s];
NSLog(@"res %@", res);
}
@catch (NSException *exception) {
NSLog(@"Parse Error:%@", exception);
}
你会得到一个很好的人类可读错误:
Parse Error:
After : ( + a
Expected : Alternation (term)
Found : -
希望有帮助。