Objective c 如何使用ParseKit框架查找解析错误

Objective c 如何使用ParseKit框架查找解析错误,objective-c,parsekit,Objective C,Parsekit,我想知道在遇到语法错误之前,是否有办法返回PKParser解析程序集的距离 参考: 我使用的语法基本上描述了前缀符号表达式语言 例如: 给定您的标准前缀符号表达式语法和字符串“(+a-bc))” 我想在匹配的地方检索[(,+,a],这样我可以让用户知道在哪里查找以修复错误,但是completeMatchFor和bestMatchFor不会返回任何我可以用来查找此信息的内容 理想情况下,我想说的是应该有一个“(”,但对于像我所使用的那样简单的语法来说,这并不是必需的 从《用户手册》中提到的那本书来

我想知道在遇到语法错误之前,是否有办法返回PKParser解析程序集的距离

参考:

我使用的语法基本上描述了前缀符号表达式语言

例如:

给定您的标准前缀符号表达式语法和字符串“(+a-bc))” 我想在匹配的地方检索[(,+,a],这样我可以让用户知道在哪里查找以修复错误,但是completeMatchFor和bestMatchFor不会返回任何我可以用来查找此信息的内容

理想情况下,我想说的是应该有一个“(”,但对于像我所使用的那样简单的语法来说,这并不是必需的

从《用户手册》中提到的那本书来看,似乎我需要为此创建一个自定义解析器,但我希望我只是错过了框架中的一些东西

想法?

这里的开发者

ParseKit中有两个特性可用于帮助提供用户可读的提示,以描述输入中遇到的解析错误

  • -[PKParser bestMatchFor:]
  • PKTrack
  • 听起来您好像知道
    -bestMatchFor:
    方法,即使它没有达到您在本例中预期的效果

    我认为
    PKTrack
    类在这里会更有用。如中所述,
    PKTrack
    PKSequence
    完全相同,只是它的子parser是必需的,并且当它的所有子parser都不匹配时会抛出一个错误(带有有用的错误消息)

    下面是示例输入的语法:

    @start         = '(' expr ')' | expr;
    expr           = ('+' | '-') term term;
    term           = '(' expr ')' | Word;
    
    连续列出的任何作品都是一个序列,但也可以是一个曲目

    将这些序列更改为轨迹的好处是,如果输入不匹配,则会抛出一条人类可读的解析错误消息。缺点是现在必须将工厂生成的解析器的所有用法包装在try/catch块中,以捕获这些轨迹异常

    目前(至少在现在之前)的问题是,
    PKParserFactory
    从未生成使用轨迹的解析器,而是始终使用序列

    因此,我刚刚在(您需要进行udpate)的躯干头部添加了一个新选项

    默认情况下为
    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 : -
    

    希望这会有所帮助。

    我也在努力解决这个问题。为了使
    -bestMatchFor:
    在识别错误条件方面有用,在
    PKAssembly
    的公共界面中应该有方法指示是否有更多的令牌/字符需要解析。
    -completeMatchFor:
    能够确定错误状态se它可以访问私有的
    -hasMore
    方法。也许
    PKAssembly
    -hasMore
    方法应该是公共的

    我查看了
    PKTrack
    ,但由于我希望以编程方式处理错误,因此它对我没有用处

    我的结论是,要么编写自己的自定义轨迹解析器,要么修改框架并公开
    -hasMore
    。还有其他方法来处理错误吗

    在找到更好的错误检测方法之前,我已将以下内容添加到包含自定义解析器实现的文件中:

    @interface PKAssembly ()
    - (BOOL)hasMore;
    - (id)peek;
    @end
    
    @implementation PMParser
    ...
    @end
    
    在我的解析方法中:

    PKAssembly*     a     = [PKTokenAssembly assemblyWithString:s];
    PKAssembly*     best  = [self bestMatchFor:a];
    PMParseNode*    node  = nil;
    BOOL            error = NO;
    NSUInteger      errorOffset = 0;
    
    if (best == nil)  // Anything recognized?
    {   
        error = YES;
    }
    else
    {
        if ([best hasMore])  // Partial recognition?
        {
            PKToken*    t = [best peek];
    
            error       = YES;
            errorOffset = t.offset;
        }
    
        node = [best pop];
    }
    
    如果发生错误,
    errorOffset
    将包含无法识别的令牌的位置

    @interface PKAssembly ()
    - (BOOL)hasMore;
    - (id)peek;
    @end
    
    @implementation PMParser
    ...
    @end
    
    PKAssembly*     a     = [PKTokenAssembly assemblyWithString:s];
    PKAssembly*     best  = [self bestMatchFor:a];
    PMParseNode*    node  = nil;
    BOOL            error = NO;
    NSUInteger      errorOffset = 0;
    
    if (best == nil)  // Anything recognized?
    {   
        error = YES;
    }
    else
    {
        if ([best hasMore])  // Partial recognition?
        {
            PKToken*    t = [best peek];
    
            error       = YES;
            errorOffset = t.offset;
        }
    
        node = [best pop];
    }