Question

Having got to grips a bit with the ParseKit grammar syntax (playing around in the demo app) I'm now trying to get my own mini demo working, but so far without much success. The assembler callbacks are not getting called.

Below is a condensed version of the relevant code. When testParse runs the parser seems to do it's thing OK and correctly match my string to my anything production (which also works in the demo) but didMatchAnything: is just not getting called.

#import <Foundation/Foundation.h>

@class PKParser;

@interface FileParserThing : NSObject {
    PKParser* _parser;
}
- (void)testParse;
@end


#import <ParseKit/ParseKit.h>
#import "FileParserThing.h"

@interface FileParserThing ()
@property (nonatomic, retain)PKParser* parser;
- (void)didMatchAnything:(PKAssembly *)a;
@end

@implementation FileParserThing

@synthesize parser = _parser;

-(id)init
{
    if (!(self = [super init])) return nil;

    NSString *g = @"@start = anything; anything = Any+;";
    self.parser = [[PKParserFactory factory] parserFromGrammar:g assembler:self];

    return self;
}

- (void)testParse
{
    NSString *s = @"Foo Bar";
    NSLog(@"test parse with: %@", s);
    [self.parser parse:s];
}

- (void)didMatchAnything:(PKAssembly *)a
{
    NSLog(@"Hooray!");
}

@end

Digging around in the ParseKit code I can see that line 129 of PKParser

[assembler performSelector:assemblerSelector withObject:self withObject:a];

Isn't being executed, because assembler is nil. Which, in turn, leads me to the parser factory; where my understanding of what's going on begins to fail.

Disclaimer; I know, I probably need to read The Book, but one thing at a time. I want to get a small proof of concept working, before forking out 30 mice for a book I might never read again if my project is a non-starter :)

Was it helpful?

Solution

Developer of ParseKit here.

A while back I changed the signature of the Assembler callbacks to accept two arguments:

  1. The Parser which matched the current token.
  2. The Assembly containing the current state of the input parsing.

Previously, there had only been one argument: The Assembly.

I'm not sure the docs are fully updated to reflect this.

So I suspect that if you simply change your Assembler callback method to this, it will work:

- (void)parser:(PKParser *)p didMatchAnything:(PKAssembly *)a {
    NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
}

If not, let me know, and I'll help to further debug.


For background: I made this change because I ran into a situation where my Assembler callback really needed to inspect the Parser which had just made the current match.

It also aligned more closely the strong Cocoa convention of Delegate callbacks which always have the delegator object as their first argument. In hindsight I kinda wish I had renamed the whole concept of Assemblers in ParseKit to Delegates. Since in Cocoa parlance, that's basically what Assemblers are.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top