2

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行ずつ読み取ることで(とにかくパフォーマンスが向上する可能性がありますか?)、おそらくこれを回避できますが、「\n」に一致するオプションがあると便利です。

4

1 に答える 1

2

ここでParseKitの開発者。私が貢献できる2つのこと:


1.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.2。

しかし、実際にあなたの例が機能したことに少し驚いていました。プロダクションを使用すると、ラインの最後にあるトークンAny*が貪欲に消費され、プロダクションに一致するものが何も残らないと思ったからです。\neol

ただし、前述したように、(トランクのParseKit HEADに対して)例を実行した場合、これは問題ではありませんでした。

それでも、適切な測定のために、私はおそらくあなたのtextline生産をこれに変更することをお勧めします:

textline = ~eol* eol;

このプロダクションの定義は次のように読む必要があります。

一致しないトークンが0個以上ありeol、その後に一致するトークンが1つeol

~ParseKit文法構文のブール否定演算子です。

サンプルコードにこの変更を加えた後も、すべてが期待どおりに機能しました。


これらの2つのヒントを実行しても機能しない場合は、お知らせください。

于 2012-03-12T21:00:37.360 に答える