ParseKit не соответствует моим символам EOL:Что я делаю не так?

StackOverflow https://stackoverflow.com//questions/9672893

Вопрос

Приключение на Парсеките продолжается...и мое следующее препятствие - попытка распознать символы новой строки.

Вот моя грамматика:

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

Вот мой тестовый текст:

1
2
3
4
5

Текст считывается из текстового файла UTF-8 с окончаниями строк в формате Unix (LF).Я проверил этот формат как в Xcode (инспектор файлов -> Настройки текста), так и извне, с помощью TextWrangler.

И вот соответствующий код:

#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

Но я боюсь, что краска просто не высыхает!Перепробовали всевозможные вариации на тему вышесказанного.Я ни за что на свете не могу заставить синтаксический анализатор распознать новую строку.Вероятно, я могу обойти это, читая файловый буфер построчно (что в любом случае может быть более производительным?), но все равно было бы неплохо иметь возможность сопоставления ' '.

Это было полезно?

Решение

Разработчик ПарсеКит здесь.Я могу внести свой вклад в две вещи:


1.

Я попробовал ваш пример, используя текстовый файл, созданный либо в TextMate, либо в TextWrangler (сохраненный как текстовый файл .txt), и все, казалось, работало нормально.Мой -parser:didMatchEol: и -parser:didMatchTexline: обратные вызовы были вызваны, как и ожидалось.

Если это у вас не работает, возможно, попробуйте начать с ввода строки в памяти, чтобы посмотреть, сработает ли хотя бы это:

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

В любом случае, вот мой код из DebugAppDelegate.m который работает для меня либо с вводом в память, либо с вводом на диске:

- (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.

Однако на самом деле я был немного удивлен, что ваш пример сработал, поскольку я думал, что вы используете Any* производство жадно поглотило бы \n жетоны в конце строки, таким образом, ничего не оставляя для eol производство под стать.

Однако, как я уже упоминал, это не было проблемой, когда я запускал ваш пример (против ParseKit HEAD of trunk).

Тем не менее, для пущей убедительности, я бы, вероятно, порекомендовал изменить ваш textline производство к этому:

textline = ~eol* eol;

определение этого производства следует читать следующим образом:

ноль или более токенов, НЕ совпадающих с eol, за которым следует один токен , соответствующий eol

~ является логическим оператором отрицания в синтаксисе грамматики ParseKit.

После внесения этого изменения в мой пример кода все по-прежнему работало так, как ожидалось.


Если вы все еще не можете заставить его работать после этих двух советов, дайте мне знать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top