ParseKit ассемблера не вызывается: что я делаю не так? - PullRequest
3 голосов
/ 10 марта 2012

Немного разобравшись с синтаксисом грамматики ParseKit (игра в демо-приложении), я сейчас пытаюсь заставить работать мою собственную мини-демонстрацию, но пока без особого успеха. Обратные вызовы ассемблера не вызываются.

Ниже приведена сокращенная версия соответствующего кода. Когда testParse запускается, парсер, кажется, все делает нормально и правильно сопоставляет мою строку с моим anything продукцией (которая также работает в демоверсии), но didMatchAnything: просто не вызывается.

#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

Копаясь в коде ParseKit, я вижу эту строку 129 PKParser

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

Не выполняется, потому что assembler - ноль. Что, в свою очередь, приводит меня к фабрике парсеров; где мое понимание того, что происходит, начинает терпеть неудачу.

Отказ от ответственности; Я знаю, что, наверное, мне нужно прочитать Книгу , но по одной вещи за раз. Я хочу получить небольшое доказательство работоспособности концепции, прежде чем раскошелиться на 30 мышей для книги, которую я мог бы никогда больше не прочитать, если мой проект не начальный:)

1 Ответ

5 голосов
/ 10 марта 2012

Разработчик ParseKit здесь.

Некоторое время назад я изменил подпись обратных вызовов Ассемблера, чтобы принять два аргумента:

  1. Parser , который соответствует текущему токену.
  2. Сборка , содержащая текущее состояние синтаксического анализа ввода.

Раньше был только один аргумент: Ассамблея.

Я не уверен, что документы полностью обновлены, чтобы отразить это.

Так что я подозреваю, что если вы просто измените свой метод обратного вызова Ассемблера на это, он будет работать:

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

Если нет, дайте мне знать, и я помогу в дальнейшей отладке.


Для справки: я сделал это изменение, потому что столкнулся с ситуацией, когда моему обратному вызову Ассемблера действительно нужно было проверить Парсер, который только что сделал текущее совпадение.

Он также более точно выровнял строгую конвенцию о какао Delegate callbacks, которая всегда имеет объект Delegator в качестве первого аргумента. Оглядываясь назад, я бы хотел переименовать всю концепцию Ассемблеры в ParseKit в Делегаты . Так как на языке какао, это в основном то, что ассемблеры.

...