3

PK を使用して .gift ファイル形式をトークン化しようとしています。私は次のことをしようとしています:

@"= 2 + 2" のような文字列があるとします。

その文字列を通過するトークンがシンボルと等しいかどうかを判断し、出力文字列がどうあるべきかを定義する手間をかけずに、「2 + 2」を返そうとしています。私がやろうとしているのは、[PKToken.stringValue isEqualToString: @"="] の場合、その値を PKTokenizer からポップし、残りの文字列をそのままの形式で返すことです。

これが十分に明確かどうか教えてください...

――スカイラー。

4

2 に答える 2

2

ParseKitの開発者はこちら。これが私のParseKit Grammar Answerです。

繰り返しますが、個々の文字の単純なフィルタリングは、おそらく ParseKit よりも正規表現を使用した方がうまくいくと言わざるを得ません。

とはいえ、 ParseKit grammarでこの種のことをしようとしている場合は、次の 1 つの方法があります。

私の文法:

@reportsWhitespaceTokens = YES;

@start = (reject! | passThru)+;
reject = '=';
passThru = ~reject;

つまり、この token を破棄し!ます。はLogical Notです。~

このアセンブラー コールバックを定義します。

- (void)parser:(PKParser *)p didMatchPassThru:(PKAssembly *)a {
    NSLog(@"%s %@", __PRETTY_FUNCTION__, a);
    PKToken *tok = [a pop];
    if (!a.target) {
        a.target = [NSMutableArray array];
    }
    [a.target addObject:tok];
}

ご覧のとおり、アセンブリのターゲットとして格納されている配列にpassThruトークンを蓄積するだけです。

私のドライバーコード:

NSString *g = // fetch grammar above
PKParser *p = [[PKParserFactory factory] parserFromGrammar:g assembler:self];
NSString *s = @"= 2 + 2";

NSArray *toks = [p parse:s];
NSString *result = [toks componentsJoinedByString:@""];
NSLog(@"res '%@'", result);
NSAssert([result isEqualToString:@"2 + 2"], @"");

最後に、蓄積されたトークン (アセンブリのターゲット) をフェッチし、それらを文字列に結合します。

于 2012-04-10T02:37:29.990 に答える
2

ParseKitの開発者はこちら。これが私のParseKit Tokenizer Answerです。

まず、個々の文字の単純なフィルタリングは、おそらく ParseKit よりも正規表現を使用した方がうまくいくと言わざるを得ません。

そうは言っても、 ParseKit tokenizerでこの種のことをしようとしている場合は、次のようになります。

NSString *s = @"= 2 + 2";
PKTokenizer *t = [PKTokenizer tokenizerWithString:s];
t.whitespaceState.reportsWhitespaceTokens = YES;

PKToken *eof = [PKToken EOFToken];
PKToken *tok = nil;

NSMutableArray *toks = [NSMutableArray array];
while ((tok = [t nextToken]) != eof) {
    if (![tok.stringValue isEqualToString:@"="]) {
        [toks addObject:tok];
    }
}

NSString *result = [toks componentsJoinedByString:@""];
NSLog(@"%@", result);
于 2012-04-10T02:03:57.483 に答える