ParseKit冒险继续......我的下一个障碍是尝试识别换行符号。
这是我的语法:
@symbolState = '\n';
@start = textline*;
textline = Any* eol;
eol = '\n';
这是我的测试文字:
1
2
3
4
5
正在从具有Unix格式(LF)行结尾的UTF-8文本文件中读取文本。我已经使用TextWrangler在Xcode(文件检查器 - >文本设置)和外部验证了这种格式。
以下是相关代码:
#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
但我担心油漆不干燥!在上面尝试了各种各样的变化。我不能为我的生活让解析器识别换行符。我可以通过逐行读取文件缓冲区来解决这个问题(无论如何都可能更高效?)但是选择匹配'\ n'仍然会很好。
答案 0 :(得分:2)
ParseKit的开发人员。我可以做出两件事:
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),这不是问题。
尽管如此,我还是建议您将textline
制作改为:
textline = ~eol* eol;
该产品的定义应理解为:
零个或多个令牌与eol
不匹配,后跟一个与eol
匹配的令牌
~
是ParseKit语法语法中的布尔否定运算符。
对我的示例代码进行此更改后,所有内容仍按预期工作。
<小时/> 如果你仍然无法在这两个提示后工作,请告诉我。