ParseKit冒险仍在继续。..我的下一个障碍是试图识别换行符。

这是我的语法:

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

这是我的测试文本:

1
2
3
4
5

文本是从UNIX格式(LF)行结尾的UTF-8文本文件中读取的.我已经在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中创建的文本文件(保存为a)尝试了您的示例。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主干头)时,这不是一个问题。

不过,为了更好的衡量标准,我可能会建议改变你的 textline 生产到这个:

textline = ~eol* eol;

这种生产的定义应理解为:

零个或多个未匹配的令牌 eol, ,后跟一个令牌匹配 eol

~ 是ParseKit语法语法中的布尔否定运算符。

对我的示例代码进行此更改后,一切仍然按预期工作。


如果你仍然不能得到这两个提示后,它的工作,让我知道。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top