Pergunta

Tendo me familiarizado um pouco com a sintaxe gramatical do ParseKit (brincando no aplicativo de demonstração), agora estou tentando fazer minha própria mini demonstração funcionar, mas até agora sem muito sucesso.Os retornos de chamada do assembler não estão sendo chamados.

Abaixo está uma versão condensada do relevante código.Quando testParse executa o analisador parece fazer tudo certo e combinar corretamente minha string com minha anything produção (que também funciona na demonstração), mas didMatchAnything:simplesmente não é ser chamado.

#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

Pesquisando no código do ParseKit, posso ver a linha 129 do PKParser

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

Não está sendo executado, porque assembler é nulo.O que, por sua vez, me leva à fábrica do analisador;onde minha compreensão do que está acontecendo começa a falhar.

Isenção de responsabilidade;Eu sei, provavelmente preciso ler O livro, Mas uma coisa de cada vez.Quero que uma pequena prova de conceito funcione, antes de desembolsar 30 ratos para um livro que talvez nunca mais leia se meu projeto não for inicial :)

Foi útil?

Solução

Desenvolvedor do ParseKit aqui.

Há algum tempo, mudei a assinatura dos retornos de chamada do Assembler para aceitar dois argumentos:

  1. O Analisador que correspondeu ao token atual.
  2. O Conjunto contendo o estado atual da análise de entrada.

Anteriormente, só havia um argumento:A montagem.

Não tenho certeza se os documentos estão totalmente atualizados para refletir isso.

Então eu suspeito que se você simplesmente mudar seu método de retorno de chamada do Assembler para isso, ele funcionará:

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

Caso contrário, avise-me e ajudarei a depurar ainda mais.


Para plano de fundo:Fiz essa alteração porque me deparei com uma situação em que meu retorno de chamada do Assembler realmente precisava inspecionar o analisador que acabara de fazer a correspondência atual.

Também alinhou mais estreitamente a forte Convenção do Cacau de Delegar retornos de chamada que sempre têm o delegador objeto como seu primeiro argumento.Em retrospectiva, eu gostaria de ter renomeado todo o conceito de Montadores no ParseKit para Delegados.Já que no jargão do Cacau, isso é basicamente o que os Montadores são.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top