Pergunta

A aventura do ParseKit continua...e meu próximo obstáculo é tentar fazer com que os símbolos de nova linha sejam reconhecidos.

Aqui está minha gramática:

@symbolState = '\n';
@start = textline*;
textline = Any* eol;
eol = '\n';

Aqui está meu texto de teste:

1
2
3
4
5

O texto está sendo lido de um arquivo de texto UTF-8 com finais de linha no formato Unix (LF).Verifiquei esse formato tanto no Xcode (inspetor de arquivos -> Configurações de texto) quanto externamente, com TextWrangler.

E aqui está o código relevante:

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

@interface FileImporterThing ()
@property (nonatomic, retain)PKParser* parser;
- (void)parser:(PKParser *)p didMatchTextline:(PKAssembly *)a;
- (void)parser:(PKParser *)p didMatchEol:(PKAssembly *)a;
@end


@implementation FileImporterThing

@synthesize parser = _parser;

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

    // Have also tried "textline = Any* '\n';"
    NSString *g = @"@symbolState = '\n'; @start = textline*; textline = Any* eol; eol = '\n';";
    self.parser = [[PKParserFactory factory] parserFromGrammar:g assembler:self];

    return self;
}

- (void)testParse
{
    // read string from UTF-8 file Unix (LF) line endings 
    // (this verified in project->file inspector->Text Settings and externally with TextWrangler)
    NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"LF-test" ofType:@"parsetext"];
/* file contains text:
1
2
3
4
5

*/
    NSString *s = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

    [self.parser parse:s];
}

- (void)parser:(PKParser *)p didMatchEol:(PKAssembly *)a
{
    NSLog(@"eol found");// stack = %@", [a stack]);
}

- (void)parser:(PKParser *)p didMatchTextline:(PKAssembly *)a
{
    NSLog(@"textline matched");
}

@end

Mas temo que a tinta simplesmente não esteja secando!Tentei todos os tipos de variações acima.Não consigo fazer com que o analisador reconheça uma nova linha.Provavelmente posso contornar isso lendo o buffer de arquivo linha por linha (o que pode ter melhor desempenho, de qualquer maneira?), Mas ainda seria bom ter a opção de combinar ' '.

Foi útil?

Solução

Desenvolvedor de Kit de análise aqui.Duas coisas que posso contribuir:


1.

Tentei seu exemplo usando um arquivo de texto criado no TextMate ou no TextWrangler (salvo como um arquivo .txt) e tudo pareceu funcionar bem.Meu -parser:didMatchEol: e -parser:didMatchTexline: retornos de chamada foram chamados conforme o esperado.

Se isso não estiver funcionando para você, tente começar com a entrada de string na memória para ver se pelo menos isso funcionará:

NSString *s = @"foo bar\nbaz bat\n";
[parser parse:s];

De qualquer forma, aqui está o meu código de DebugAppDelegate.m que está funcionando para mim com entrada na memória ou entrada no disco:

- (void)doTestGrammar {
    NSString *g = @"@symbolState = '\n'; @start = textline*; textline = Any* eol; eol = '\n';";
    PKParser *p = [[PKParserFactory factory] parserFromGrammar:g assembler:self];
    //NSString *s = @"foo bar\nbaz bat\n";
    NSString *path = [@"~/Desktop/text.txt" stringByExpandingTildeInPath];
    NSString *s = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    [p parse:s];
}

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

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

2.

Na verdade, fiquei um pouco surpreso que seu exemplo tenha funcionado, pois pensei que seu uso do Any* a produção consumiria avidamente o \n tokens no final da linha, não deixando nada para o eol produção a combinar.

Porém, como mencionei, isso não foi um problema quando executei seu exemplo (no ParseKit HEAD do tronco).

Ainda assim, para garantir, eu provavelmente recomendaria alterar seu textline produção para isso:

textline = ~eol* eol;

a definição desta produção deve ser lida como:

zero ou mais tokens NÃO correspondidos por eol, seguido por um token correspondido por eol

~ é o operador de negação booleano na sintaxe gramatical do ParseKit.

Depois de fazer essa alteração no meu código de exemplo, tudo ainda funcionou conforme o esperado.


Se você ainda não conseguir fazer funcionar depois dessas duas dicas, me avise.

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