3

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 :)

Rich
  • 532
  • 3
  • 17

1 Answers1

5

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.

Todd Ditchendorf
  • 11,217
  • 14
  • 69
  • 123
  • Rich, I setup your example here with my suggested adjustment, and it does seem to work, so this should be it. – Todd Ditchendorf Mar 10 '12 at 15:59
  • Great stuff, that did it. Thanks very much for such a quick response! – Rich Mar 10 '12 at 17:02
  • Would be great if you could update your website with more up-to-date examples, including the usage of the error: params and the new parser: param as well. Otherwise, ParseKit looks awesome! – Grimless Dec 07 '12 at 07:43
  • @Todd It would be great if you put all the ParseKit docs on the proejct's GitHub wiki so that users can edit the docs. If they were user editable, I could easily make these changes to the docs right this very moment. – Xander Dunn Apr 17 '13 at 06:51
  • @ToddDitchendorf - That did the trick. The bottom of this page needs to be updated: http://parsekit.com/grammars.html - I was using the example right on the page and it wasn't working until I changed my signatures as you suggested in this answer. Quick unrelated question for you: I'm making an Xcode plugin that utilizes your plugin for parsing code the user types. What do I need to do to comply with the licenses in ParseKit? I'd rather not release the source code if possible, but if that's necessary I can do it... – ArtOfWarfare May 26 '13 at 05:40