Pregunta

La aventura de ParseKit continúa...y mi próximo obstáculo es intentar que se reconozcan los símbolos de nueva línea.

Aquí está mi gramática:

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

Aquí está mi texto de prueba:

1
2
3
4
5

El texto se lee desde un archivo de texto UTF-8 con finales de línea en formato Unix (LF).He verificado ese formato tanto en Xcode (inspector de archivos -> Configuración de texto) como externamente, con TextWrangler.

Y aquí está el 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

¡Pero me temo que la pintura no se seca!He probado todo tipo de variaciones de lo anterior.No puedo por mi vida hacer que el analizador reconozca una nueva línea.Probablemente pueda solucionar este problema leyendo el búfer de archivos línea por línea (¿cuál podría ser más eficaz de todos modos?), pero aún así sería bueno tener la opción de hacer coincidir ' '.

¿Fue útil?

Solución

Desarrollador de Kit de análisis aquí.Dos cosas puedo aportar:


1.

Probé su ejemplo usando un archivo de texto creado en TextMate o TextWrangler (guardado como un archivo .txt) y todo pareció funcionar bien.Mi -parser:didMatchEol: y -parser:didMatchTexline: Las devoluciones de llamada se realizaron como se esperaba.

Si esto no funciona para usted, tal vez intente comenzar con la entrada de cadena en memoria para ver si al menos eso funciona:

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

De todos modos, aquí está mi código de DebugAppDelegate.m que me funciona ya sea con entrada en memoria o con entrada en 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.

De hecho, me sorprendió un poco que su ejemplo funcionara, ya que pensé que su uso del Any* la producción consumiría con avidez el \n fichas al final de la línea, sin dejar nada para el eol producción a la altura.

Sin embargo, como mencioné, esto no fue un problema cuando ejecuté su ejemplo (contra ParseKit HEAD del tronco).

Aún así, por si acaso, probablemente recomendaría modificar su textline producción a esto:

textline = ~eol* eol;

la definición de esta producción debe leerse como:

cero o más tokens NO coincidentes con eol, seguido de un token que coincida con eol

~ es el operador de negación booleano en la sintaxis gramatical de ParseKit.

Después de realizar este cambio en mi código de ejemplo, todo funcionó como se esperaba.


Si aún no logras que funcione después de estos dos consejos, házmelo saber.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top